Attachment 'mriio.c'

Download

   1 /*
   2  *       FILE NAME:   mriio.c
   3  *
   4  *       DESCRIPTION: utilities for reading/writing MRI data structure
   5  *
   6  *       AUTHOR:      Bruce Fischl
   7  *       DATE:        4/12/97
   8  *
   9  */
  10 
  11 /*-----------------------------------------------------
  12   INCLUDE FILES
  13   -------------------------------------------------------*/
  14 #define USE_ELECTRIC_FENCE 1
  15 #define _MRIIO_SRC
  16 
  17 #include <stdio.h>
  18 #include <stdlib.h>
  19 #include <string.h>
  20 #include <math.h>
  21 #include <string.h>
  22 #include <ctype.h>
  23 #include <unistd.h>
  24 #include <memory.h>
  25 #include <sys/stat.h>
  26 #include <sys/types.h>
  27 #include <ctype.h>
  28 #include <dirent.h>
  29 #include <time.h>
  30 #include <errno.h>
  31 #include <fcntl.h>
  32 
  33 #include "utils.h"
  34 #include "error.h"
  35 #include "proto.h"
  36 #include "mri.h"
  37 #include "macros.h"
  38 #include "diag.h"
  39 #include "volume_io.h"
  40 #include "region.h"
  41 #include "machine.h"
  42 #include "analyze.h"
  43 #include "fio.h"
  44 #include "mri_identify.h"
  45 #include "signa.h"
  46 #include "fio.h"
  47 #include "matfile.h"
  48 #include "math.h"
  49 #include "matrix.h"
  50 #include "diag.h"
  51 #include "chklc.h"
  52 #include "mriColorLookupTable.h"
  53 #include "DICOMRead.h"
  54 #include "imautils.h"
  55 #include "cma.h"
  56 #include "Bruker.h"
  57 #include "bfileio.h"
  58 #include "AFNI.h"
  59 #include "mghendian.h"
  60 #include "tags.h"
  61 #ifdef Darwin
  62 // /usr/include/zconf.h should typedef Byte, but doesnt on the Mac:
  63 typedef unsigned char  Byte;  /* 8 bits */
  64 #endif
  65 #include "nifti1.h"
  66 #include "znzlib.h"
  67 
  68 // unix director separator
  69 #define DIR_SEPARATOR '/'
  70 #define CURDIR "./"
  71 
  72 #define MM_PER_METER  1000.0f
  73 #define INFO_FNAME    "COR-.info"
  74 
  75 #ifdef Linux
  76 extern void swab(const void *from, void *to, size_t n);
  77 #endif
  78 
  79 #if 0
  80 static int NormalizeVector(float *v, int n);
  81 static MRI *mincRead2(char *fname, int read_volume);
  82 static int mincWrite2(MRI *mri, char *fname);
  83 static int GetMINCInfo(MRI *mri,
  84                        char *dim_names[4],
  85                        int   dim_sizes[4],
  86                        Real separations[4],
  87                        Real dircos[3][3],
  88                        Real VolCenterVox[3],
  89                        Real VolCenterWorld[3]);
  90 #endif
  91 
  92 static MRI *mri_read
  93 (char *fname, int type, int volume_flag, int start_frame, int end_frame);
  94 static MRI *corRead(char *fname, int read_volume);
  95 static int corWrite(MRI *mri, char *fname);
  96 static MRI *siemensRead(char *fname, int read_volume);
  97 static MRI *readGCA(char *fname) ;
  98 
  99 static MRI *mincRead(char *fname, int read_volume);
 100 static int mincWrite(MRI *mri, char *fname);
 101 static int bvolumeWrite(MRI *vol, char *fname_passed, int type);
 102 //static int bshortWrite(MRI *mri, char *fname_passed);
 103 //static int bfloatWrite(MRI *mri, char *stem);
 104 static int write_bhdr(MRI *mri, FILE *fp);
 105 static int read_bhdr(MRI *mri, FILE *fp);
 106 
 107 static MRI *bvolumeRead(char *fname_passed, int read_volume, int type);
 108 //static MRI *bshortRead(char *fname_passed, int read_volume);
 109 //static MRI *bfloatRead(char *fname_passed, int read_volume);
 110 static MRI *genesisRead(char *stem, int read_volume);
 111 static MRI *gelxRead(char *stem, int read_volume);
 112 
 113 static int CountAnalyzeFiles(char *analyzefname, int nzpad, char **ppstem);
 114 static MRI *analyzeRead(char *fname, int read_volume);
 115 static dsr *ReadAnalyzeHeader(char *hdrfile, int *swap,
 116                               int *mritype, int *bytes_per_voxel);
 117 static int DumpAnalyzeHeader(FILE *fp, dsr *hdr);
 118 
 119 
 120 static int analyzeWrite(MRI *mri, char *fname);
 121 static int analyzeWriteFrame(MRI *mri, char *fname, int frame);
 122 static int analyzeWriteSeries(MRI *mri, char *fname);
 123 static int analyzeWrite4D(MRI *mri, char *fname);
 124 
 125 static void swap_analyze_header(dsr *hdr);
 126 
 127 #if 0
 128 static int orient_with_register(MRI *mri);
 129 #endif
 130 static int nan_inf_check(MRI *mri);
 131 #ifdef VC_TO_CV
 132 static int voxel_center_to_center_voxel
 133 (MRI *mri, float *x, float *y, float *z);
 134 #endif
 135 static MRI *gdfRead(char *fname, int read_volume);
 136 static int gdfWrite(MRI *mri, char *fname);
 137 
 138 static MRI *ximgRead(char *fname, int read_volume);
 139 
 140 static MRI *nifti1Read(char *fname, int read_volume);
 141 static int nifti1Write(MRI *mri, char *fname);
 142 static MRI *niiRead(char *fname, int read_volume);
 143 static int niiWrite(MRI *mri, char *fname);
 144 static int niftiQformToMri(MRI *mri, struct nifti_1_header *hdr);
 145 static int mriToNiftiQform(MRI *mri, struct nifti_1_header *hdr);
 146 static int niftiSformToMri(MRI *mri, struct nifti_1_header *hdr);
 147 static void swap_nifti_1_header(struct nifti_1_header *hdr);
 148 static MRI *MRISreadCurvAsMRI(char *curvfile, int read_volume);
 149 
 150 /********************************************/
 151 
 152 static void short_local_buffer_to_image
 153 (short *buf, MRI *mri, int slice, int frame) ;
 154 
 155 static void int_local_buffer_to_image
 156 (int *buf, MRI *mri, int slice, int frame) ;
 157 
 158 static void long32_local_buffer_to_image
 159 (long32 *buf, MRI *mri, int slice, int frame) ;
 160 
 161 static void float_local_buffer_to_image
 162 (float *buf, MRI *mri, int slice, int frame) ;
 163 
 164 static void local_buffer_to_image
 165 (BUFTYPE *buf, MRI *mri, int slice, int frame) ;
 166 
 167 static MRI *sdtRead(char *fname, int read_volume);
 168 static MRI *mghRead(char *fname, int read_volume, int frame) ;
 169 static int mghWrite(MRI *mri, char *fname, int frame) ;
 170 static int mghAppend(MRI *mri, char *fname, int frame) ;
 171 
 172 /********************************************/
 173 
 174 extern int errno;
 175 
 176 extern char *Progname;
 177 /*char *Progname;*/
 178 
 179 static char *command_line;
 180 static char *subject_name;
 181 
 182 #define MAX_UNKNOWN_LABELS  100
 183 
 184 static short cma_field[512][512];
 185 static char unknown_labels[MAX_UNKNOWN_LABELS][STRLEN];
 186 static int n_unknown_labels;
 187 
 188 //////////////////////////////////////////////////////////////////////
 189 // this is a one way of setting direction cosine
 190 // when the direction cosine is not provided in the volume.
 191 // may not agree with the volume. what can we do?  Let them set by themselves.
 192 int setDirectionCosine(MRI *mri, int orientation)
 193 {
 194   switch(orientation)
 195     {
 196     case MRI_CORONAL: // x is from right to left.
 197                       // y is from top to neck, z is from back to front
 198       mri->x_r = -1; mri->y_r =  0; mri->z_r =  0; mri->c_r = 0;
 199       mri->x_a =  0; mri->y_a =  0; mri->z_a =  1; mri->c_a = 0;
 200       mri->x_s =  0; mri->y_s = -1; mri->z_s =  0; mri->c_s = 0;
 201       break;
 202     case MRI_SAGITTAL: // x is frp, back to front,
 203                        // y is from top to neck, z is from left to right
 204       mri->x_r =  0; mri->y_r =  0; mri->z_r =  1; mri->c_r = 0;
 205       mri->x_a =  1; mri->y_a =  0; mri->z_a =  0; mri->c_a = 0;
 206       mri->x_s =  0; mri->y_s = -1; mri->z_s =  0; mri->c_s = 0;
 207       break;
 208     case MRI_HORIZONTAL: // x is from right to left,
 209                          // y is from front to back, z is from neck to top
 210       mri->x_r = -1; mri->y_r =  0; mri->z_r =  0; mri->c_r = 0;
 211       mri->x_a =  0; mri->y_a = -1; mri->z_a =  0; mri->c_a = 0;
 212       mri->x_s =  0; mri->y_s =  0; mri->z_s =  1; mri->c_s = 0;
 213       break;
 214     default:
 215       ErrorReturn
 216         (ERROR_BADPARM,
 217          (ERROR_BADPARM, "setDirectionCosine():unknown slice direction"));
 218       break; // should not reach here (handled at the conversion)
 219     }
 220   return (NO_ERROR);
 221 }
 222 
 223 #define isOne(a)  (fabs(fabs(a)-1)<0.00001)
 224 
 225 // here I take the narrow view of slice_direction
 226 int getSliceDirection(MRI *mri)
 227 {
 228   int direction = MRI_UNDEFINED;
 229 
 230   if (isOne(mri->x_r) && isOne(mri->y_s) && isOne(mri->z_a))
 231     direction = MRI_CORONAL;
 232   else if (isOne(mri->x_a) && isOne(mri->y_s) && isOne(mri->z_r))
 233     direction = MRI_SAGITTAL;
 234   else if (isOne(mri->x_r) && isOne(mri->y_a) && isOne( mri->z_s))
 235     direction = MRI_HORIZONTAL;
 236   return direction;
 237 }
 238 
 239 // For surface, we currently cannot handle volumes with general slice direction
 240 // nor we cannot handle non-conformed volumes
 241 int mriOKforSurface(MRI *mri)
 242 {
 243   // first check slice direction
 244   if (getSliceDirection(mri) != MRI_CORONAL)
 245     return 0;
 246   // remove slice size limitation
 247   // else if (mri->width != 256 || mri->height != 256 || mri->depth != 256)
 248   //  return 0;
 249   // remove check for 1 mm size
 250   //  else if (mri->xsize != 1 || mri->ysize != 1 || mri->zsize != 1)
 251   //  return 0;
 252   else
 253     return 1;
 254 }
 255 
 256 int mriConformed(MRI *mri)
 257 {
 258   // first check slice direction
 259   if (getSliceDirection(mri) != MRI_CORONAL)
 260     return 0;
 261   else if (mri->width != 256 || mri->height != 256 || mri->depth != 256)
 262     return 0;
 263   else if (mri->xsize != 1 || mri->ysize != 1 || mri->zsize != 1)
 264     return 0;
 265   else
 266     return 1;
 267 }
 268 
 269 void setMRIforSurface(MRI *mri)
 270 {
 271   if (!mriOKforSurface(mri))
 272     ErrorExit(ERROR_BADPARM,
 273               "%s: the volume is not conformed, that is, "
 274               "the volume must be in CORONAL direction.\n", Progname) ;
 275 #if 0
 276   else
 277     {
 278       // we checked conformed in mriOKforSurface().
 279       // The only thing missing is c_(r,a,s) = 0
 280       // for surface creation assume that the
 281       // volume is conformed and c_(r,a,s) = 0
 282       mri->c_r=mri->c_a=mri->c_s = 0;
 283       if (mri->i_to_r__)
 284         MatrixFree(&mri->i_to_r__) ;
 285       if (mri->r_to_i__)
 286         MatrixFree(&mri->r_to_i__) ;
 287       mri->i_to_r__ = extract_i_to_r(mri);
 288       mri->r_to_i__ = extract_r_to_i(mri);
 289     }
 290 #endif
 291 }
 292 
 293 int mriio_command_line(int argc, char *argv[])
 294 {
 295 
 296   int i;
 297   int length;
 298   char *c;
 299 
 300   length = 0;
 301   for(i = 0;i < argc;i++)
 302     length += strlen(argv[i]);
 303 
 304   /* --- space for spaces and \0 --- */
 305   length += argc;
 306 
 307   command_line = (char *)malloc(length);
 308 
 309   c = command_line;
 310   for(i = 0;i < argc;i++)
 311     {
 312       strcpy(c, argv[i]);
 313       c += strlen(argv[i]);
 314       *c = (i == argc-1 ? '\0' : ' ');
 315       c++;
 316     }
 317 
 318   return(NO_ERROR);
 319 
 320 } /* end mriio_command_line() */
 321 
 322 int mriio_set_subject_name(char *name)
 323 {
 324 
 325   if(subject_name == NULL)
 326     subject_name = (char *)malloc(STRLEN);
 327 
 328   if(subject_name == NULL)
 329     {
 330       errno = 0;
 331       ErrorReturn(ERROR_NO_MEMORY, (ERROR_NO_MEMORY,
 332                                     "mriio_set_subject_name(): "
 333                                     "could't allocate %d bytes...!", STRLEN));
 334     }
 335 
 336   if(name == NULL)
 337     strcpy(subject_name, name);
 338   else
 339     {
 340       free(subject_name);
 341       subject_name = NULL;
 342     }
 343 
 344   return(NO_ERROR);
 345 
 346 } /* end mriio_set_subject_name() */
 347 
 348 int MRIgetVolumeName(char *string, char *name_only)
 349 {
 350 
 351   char *at, *pound;
 352 
 353   strcpy(name_only, string);
 354 
 355   if((at = strrchr(name_only, '@')) != NULL)
 356     *at = '\0';
 357 
 358   if((pound = strrchr(name_only, '#')) != NULL)
 359     *pound = '\0';
 360 
 361   return(NO_ERROR);
 362 
 363 } /* end MRIgetVolumeName() */
 364 
 365 static MRI *mri_read
 366 (char *fname, int type, int volume_flag, int start_frame, int end_frame)
 367 {
 368   MRI *mri, *mri2;
 369   IMAGE *I;
 370   char fname_copy[STRLEN];
 371   char *ptmpstr;
 372   char *at, *pound, *colon;
 373   char *ep;
 374   int i, j, k, t;
 375   int volume_frames;
 376 
 377   // sanity-checks
 378   if(fname == NULL)
 379     {
 380       errno = 0;
 381       ErrorReturn(NULL, (ERROR_BADPARM, "mri_read(): null fname!\n"));
 382     }
 383   if(fname[0] == 0)
 384     {
 385       errno = 0;
 386       ErrorReturn(NULL, (ERROR_BADPARM, "mri_read(): empty fname!\n"));
 387     }
 388 
 389   // if filename does not contain any directory separator, then add cwd
 390   if (!strchr(fname,DIR_SEPARATOR))
 391     {
 392       char *cwd = getcwd(NULL, 0); // posix 1 extension
 393                                    // (allocate as much space needed)
 394       if (cwd)
 395         {
 396           strcpy(fname_copy, cwd);
 397           strcat(fname_copy, "/");
 398           strcat(fname_copy, fname);
 399           free(cwd);
 400         }
 401       else // why fail?
 402         strcpy(fname_copy, fname);
 403     }
 404   else
 405     strcpy(fname_copy, fname);
 406 
 407   at = strrchr(fname_copy, '@');
 408   pound = strrchr(fname_copy, '#');
 409 
 410   if(at != NULL)
 411     {
 412       *at = '\0';
 413       at++;
 414     }
 415 
 416   if(pound != NULL)
 417     {
 418       *pound = '\0';
 419       pound++;
 420     }
 421 
 422   if(at != NULL)
 423     {
 424       type = string_to_type(at);
 425       if(type == MRI_VOLUME_TYPE_UNKNOWN)
 426         {
 427           errno = 0;
 428           ErrorReturn
 429             (NULL, (ERROR_BADPARM, "mri_read(): unknown type '%s'\n", at));
 430         }
 431     }
 432   else if(type == MRI_VOLUME_TYPE_UNKNOWN)
 433     {
 434       type = mri_identify(fname_copy);
 435       if(type == MRI_VOLUME_TYPE_UNKNOWN)
 436         {
 437           errno = 0;
 438           ErrorReturn
 439             (NULL,
 440              (ERROR_BADPARM,
 441               "mri_read(): couldn't determine type of file %s", fname_copy));
 442         }
 443     }
 444 
 445   if(pound != NULL)
 446     {
 447       colon = strchr(pound, ':');
 448       if(colon != NULL)
 449         {
 450           *colon = '\0';
 451           colon++;
 452           if(*colon == '\0')
 453             {
 454               errno = 0;
 455               ErrorReturn
 456                 (NULL,
 457                  (ERROR_BADPARM,
 458                   "mri_read(): bad frame specification ('%s:')\n", pound));
 459             }
 460 
 461           start_frame = strtol(pound, &ep, 10);
 462           if(*ep != '\0')
 463             {
 464               errno = 0;
 465               ErrorReturn
 466                 (NULL,
 467                  (ERROR_BADPARM,
 468                   "mri_read(): bad start frame ('%s')\n", pound));
 469             }
 470 
 471           end_frame = strtol(colon, &ep, 10);
 472           if(*ep != '\0')
 473             {
 474               errno = 0;
 475               ErrorReturn
 476                 (NULL,
 477                  (ERROR_BADPARM,
 478                   "mri_read(): bad end frame ('%s')\n", colon));
 479             }
 480 
 481         }
 482       else
 483         {
 484           start_frame = end_frame = strtol(pound, &ep, 10);
 485           if(*ep != '\0')
 486             {
 487               errno = 0;
 488               ErrorReturn
 489                 (NULL,
 490                  (ERROR_BADPARM,
 491                   "mri_read(): bad frame ('%s')\n", pound));
 492             }
 493         }
 494 
 495       if(start_frame < 0)
 496         {
 497           errno = 0;
 498           ErrorReturn
 499             (NULL,
 500              (ERROR_BADPARM,
 501               "mri_read(): frame (%d) is less than zero\n", start_frame));
 502         }
 503 
 504       if(end_frame < 0)
 505         {
 506           errno = 0;
 507           ErrorReturn
 508             (NULL,
 509              (ERROR_BADPARM,
 510               "mri_read(): frame (%d) is less than zero\n", end_frame));
 511         }
 512 
 513       if(start_frame > end_frame)
 514         {
 515           errno = 0;
 516           ErrorReturn(NULL, (ERROR_BADPARM,
 517                              "mri_read(): the start frame (%d) is "
 518                              "greater than the end frame (%d)\n",
 519                              start_frame, end_frame));
 520         }
 521 
 522     }
 523 
 524   if(type == MRI_CORONAL_SLICE_DIRECTORY)
 525     {
 526       mri = corRead(fname_copy, volume_flag);
 527     }
 528   else if(type == SIEMENS_FILE)
 529     {
 530       mri = siemensRead(fname_copy, volume_flag);
 531     }
 532   else if (type == MRI_GCA_FILE)
 533     {
 534       mri = readGCA(fname_copy) ;
 535     }
 536   else if(type == BHDR)
 537     {
 538       ptmpstr = bhdr_firstslicefname(fname_copy);
 539       t = bhdr_precision(fname_copy);
 540       mri = bvolumeRead(ptmpstr, volume_flag, t);
 541       free(ptmpstr);
 542     }
 543   else if(type == BSHORT_FILE)
 544     {
 545       //mri = bshortRead(fname_copy, volume_flag);
 546       mri = bvolumeRead(fname_copy, volume_flag, MRI_SHORT);
 547     }
 548   else if(type == BFLOAT_FILE)
 549     {
 550       //mri = bfloatRead(fname_copy, volume_flag);
 551       mri = bvolumeRead(fname_copy, volume_flag, MRI_FLOAT);
 552     }
 553   else if(type == GENESIS_FILE)
 554     {
 555       mri = genesisRead(fname_copy, volume_flag);
 556     }
 557   else if(type == SIGNA_FILE)
 558     {
 559       mri = signaRead(fname_copy, volume_flag);
 560     }
 561   else if(type == GE_LX_FILE)
 562     {
 563       mri = gelxRead(fname_copy, volume_flag);
 564     }
 565   else if(type == MRI_ANALYZE_FILE || type == MRI_ANALYZE4D_FILE)
 566     {
 567       mri = analyzeRead(fname_copy, volume_flag);
 568     }
 569   else if(type == BRIK_FILE)
 570     {
 571       mri = afniRead(fname_copy, volume_flag);
 572     }
 573   else if(type == MRI_MINC_FILE)
 574     {
 575       //mri = mincRead2(fname_copy, volume_flag);
 576       mri = mincRead(fname_copy, volume_flag);
 577     }
 578   else if(type == SDT_FILE)
 579     {
 580       mri = sdtRead(fname_copy, volume_flag);
 581     }
 582   else if(type == MRI_MGH_FILE)
 583     {
 584       mri = mghRead(fname_copy, volume_flag, -1);
 585     }
 586   else if(type == GDF_FILE)
 587     {
 588       mri = gdfRead(fname_copy, volume_flag);
 589     }
 590   else if(type == DICOM_FILE)
 591     {
 592       DICOMRead(fname_copy, &mri, volume_flag);
 593     }
 594   else if(type == SIEMENS_DICOM_FILE)
 595     {
 596       // mri_convert -nth option sets start_frame = nth.  otherwise -1
 597       mri = sdcmLoadVolume(fname_copy, volume_flag, start_frame);
 598       start_frame = -1;
 599       // in order to avoid the later processing on start_frame and end_frame
 600       // read the comment later on
 601       end_frame = 0;
 602     }
 603   else if (type == BRUKER_FILE)
 604     {
 605       mri = brukerRead(fname_copy, volume_flag);
 606     }
 607   else if(type == XIMG_FILE)
 608     {
 609       mri = ximgRead(fname_copy, volume_flag);
 610     }
 611   else if(type == NIFTI1_FILE)
 612     {
 613       mri = nifti1Read(fname_copy, volume_flag);
 614     }
 615   else if(type == NII_FILE)
 616     mri = niiRead(fname_copy, volume_flag);
 617   else if(type == MRI_CURV_FILE)
 618     mri = MRISreadCurvAsMRI(fname_copy, volume_flag);
 619   else if (type == IMAGE_FILE) {
 620     I = ImageRead(fname_copy);
 621     mri = ImageToMRI(I);
 622     ImageFree(&I);
 623   }
 624   else
 625     {
 626       fprintf(stderr,"mri_read(): type = %d\n",type);
 627       errno = 0;
 628       ErrorReturn(NULL, (ERROR_BADPARM, "mri_read(): code inconsistency "
 629                          "(file type recognized but not caught)"));
 630     }
 631 
 632   if (mri == NULL)  return(NULL) ;
 633 
 634   // update/cache the transform
 635   if (mri->i_to_r__)
 636     MatrixFree(&(mri->i_to_r__));
 637   mri->i_to_r__ = extract_i_to_r(mri);
 638 
 639   if (mri->r_to_i__)
 640     MatrixFree(&(mri->r_to_i__));
 641   mri->r_to_i__ = extract_r_to_i(mri);
 642 
 643   /* Compute the FOV from the vox2ras matrix (don't rely on what
 644      may or may not be in the file).*/
 645 
 646   if(start_frame == -1) return(mri);
 647 
 648   /* --- select frames --- */
 649 
 650   if(start_frame >= mri->nframes)
 651     {
 652       volume_frames = mri->nframes;
 653       MRIfree(&mri);
 654       errno = 0;
 655       ErrorReturn
 656         (NULL,
 657          (ERROR_BADPARM,
 658           "mri_read(): start frame (%d) is "
 659           "out of range (%d frames in volume)",
 660           start_frame, volume_frames));
 661     }
 662 
 663   if(end_frame >= mri->nframes)
 664     {
 665       volume_frames = mri->nframes;
 666       MRIfree(&mri);
 667       errno = 0;
 668       ErrorReturn
 669         (NULL,
 670          (ERROR_BADPARM,
 671           "mri_read(): end frame (%d) is out of range (%d frames in volume)",
 672           end_frame, volume_frames));
 673     }
 674 
 675   if(!volume_flag)
 676     {
 677 
 678       if(nan_inf_check(mri) != NO_ERROR)
 679         {
 680           MRIfree(&mri);
 681           return(NULL);
 682         }
 683       mri2 = MRIcopy(mri, NULL);
 684       MRIfree(&mri);
 685       mri2->nframes = (end_frame - start_frame + 1);
 686       return(mri2);
 687 
 688     }
 689 
 690   if(start_frame == 0 && end_frame == mri->nframes-1)
 691     {
 692       if(nan_inf_check(mri) != NO_ERROR)
 693         {
 694           MRIfree(&mri);
 695           return(NULL);
 696         }
 697       return(mri);
 698     }
 699 
 700   /* reading the whole volume and then copying only
 701      some frames is a bit inelegant,
 702      but it's easier for now
 703      to do this than to insert the appropriate
 704      code into the read function for each format... */
 705   /////////////////////////////////////////////////////////////////
 706   // This method does not work, because
 707   // 1. each frame has different acq parameters
 708   // 2. when making frames, it takes the info only from the first frame
 709   // Thus taking a frame out must be done at each frame extraction
 710   ////////////////////////////////////////////////////////////////////
 711   mri2 = MRIallocSequence(mri->width,
 712                           mri->height,
 713                           mri->depth,
 714                           mri->type,
 715                           (end_frame - start_frame + 1));
 716   MRIcopyHeader(mri, mri2);
 717   mri2->nframes = (end_frame - start_frame + 1);
 718   mri2->imnr0 = 1;
 719   mri2->imnr0 = mri2->nframes;
 720 
 721   if(mri2->type == MRI_UCHAR)
 722     for(t = 0;t < mri2->nframes;t++)
 723       for(i = 0;i < mri2->width;i++)
 724         for(j = 0;j < mri2->height;j++)
 725           for(k = 0;k < mri2->depth;k++)
 726             MRIseq_vox(mri2, i, j, k, t) =
 727               MRIseq_vox(mri, i, j, k, t + start_frame);
 728 
 729   if(mri2->type == MRI_SHORT)
 730     for(t = 0;t < mri2->nframes;t++)
 731       for(i = 0;i < mri2->width;i++)
 732         for(j = 0;j < mri2->height;j++)
 733           for(k = 0;k < mri2->depth;k++)
 734             MRISseq_vox(mri2, i, j, k, t) =
 735               MRISseq_vox(mri, i, j, k, t + start_frame);
 736 
 737   if(mri2->type == MRI_INT)
 738     for(t = 0;t < mri2->nframes;t++)
 739       for(i = 0;i < mri2->width;i++)
 740         for(j = 0;j < mri2->height;j++)
 741           for(k = 0;k < mri2->depth;k++)
 742             MRIIseq_vox(mri2, i, j, k, t) =
 743               MRIIseq_vox(mri, i, j, k, t + start_frame);
 744 
 745   if(mri2->type == MRI_LONG)
 746     for(t = 0;t < mri2->nframes;t++)
 747       for(i = 0;i < mri2->width;i++)
 748         for(j = 0;j < mri2->height;j++)
 749           for(k = 0;k < mri2->depth;k++)
 750             MRILseq_vox(mri2, i, j, k, t) =
 751               MRILseq_vox(mri, i, j, k, t + start_frame);
 752 
 753   if(mri2->type == MRI_FLOAT)
 754     for(t = 0;t < mri2->nframes;t++)
 755       for(i = 0;i < mri2->width;i++)
 756         for(j = 0;j < mri2->height;j++)
 757           for(k = 0;k < mri2->depth;k++)
 758             MRIFseq_vox(mri2, i, j, k, t) =
 759               MRIFseq_vox(mri, i, j, k, t + start_frame);
 760 
 761   if(nan_inf_check(mri) != NO_ERROR)
 762     {
 763       MRIfree(&mri);
 764       return(NULL);
 765     }
 766 
 767   MRIfree(&mri);
 768 
 769   return(mri2);
 770 
 771 } /* end mri_read() */
 772 
 773 static int nan_inf_check(MRI *mri)
 774 {
 775 
 776   int i, j, k, t;
 777 
 778   if(mri->type != MRI_FLOAT)
 779     return(NO_ERROR);
 780 
 781   for(i = 0;i < mri->width;i++)
 782     for(j = 0;j < mri->height;j++)
 783       for(k = 0;k < mri->depth;k++)
 784         for(t = 0;t < mri->nframes;t++)
 785           if(!devFinite((MRIFseq_vox(mri, i, j, k, t))))
 786             {
 787               if(devIsinf((MRIFseq_vox(mri, i, j, k, t))) != 0)
 788                 {
 789                   errno = 0;
 790                   ErrorReturn
 791                     (ERROR_BADPARM,
 792                      (ERROR_BADPARM,
 793                       "nan_inf_check(): Inf at voxel %d, %d, %d, %d",
 794                       i, j, k, t));
 795                 }
 796               else if(devIsnan((MRIFseq_vox(mri, i, j, k, t))))
 797                 {
 798                   errno = 0;
 799                   ErrorReturn
 800                     (ERROR_BADPARM,
 801                      (ERROR_BADPARM,
 802                       "nan_inf_check(): NaN at voxel %d, %d, %d, %d",
 803                       i, j, k, t));
 804                 }
 805               else
 806                 {
 807                   errno = 0;
 808                   ErrorReturn
 809                     (ERROR_BADPARM,
 810                      (ERROR_BADPARM,
 811                       "nan_inf_check(): bizarre value (not Inf, "
 812                       "not NaN, but not finite) at %d, %d, %d, %d",
 813                       i, j, k, t));
 814                 }
 815             }
 816 
 817   return(NO_ERROR);
 818 
 819 } /* end nan_inf_check() */
 820 
 821 MRI *MRIreadType(char *fname, int type)
 822 {
 823 
 824   MRI *mri;
 825 
 826   chklc();
 827 
 828   mri = mri_read(fname, type, TRUE, -1, -1);
 829 
 830   return(mri);
 831 
 832 } /* end MRIreadType() */
 833 
 834 MRI *MRIread(char *fname)
 835 {
 836   char  buf[STRLEN] ;
 837   MRI *mri = NULL;
 838 
 839   chklc() ;
 840 
 841   FileNameFromWildcard(fname, buf) ; fname = buf ;
 842   mri = mri_read(fname, MRI_VOLUME_TYPE_UNKNOWN, TRUE, -1, -1);
 843 
 844   /* some volume format needs to read many
 845      different files for slices (GE DICOM or COR).
 846      we make sure that mri_read() read the slices, not just one   */
 847   if (mri==NULL)
 848     return NULL;
 849 
 850   MRIremoveNaNs(mri, mri) ;
 851   return(mri);
 852 
 853 } /* end MRIread() */
 854 
 855 // allow picking one frame out of many frame
 856 // currently implemented only for Siemens dicom file
 857 MRI *MRIreadEx(char *fname, int nthframe)
 858 {
 859   char  buf[STRLEN] ;
 860   MRI *mri = NULL;
 861 
 862   chklc() ;
 863 
 864   FileNameFromWildcard(fname, buf) ; fname = buf ;
 865   mri = mri_read(fname, MRI_VOLUME_TYPE_UNKNOWN, TRUE, nthframe, nthframe);
 866 
 867   /* some volume format needs to read many
 868      different files for slices (GE DICOM or COR).
 869      we make sure that mri_read() read the slices, not just one   */
 870   if (mri==NULL)
 871     return NULL;
 872 
 873   MRIremoveNaNs(mri, mri) ;
 874   return(mri);
 875 
 876 } /* end MRIread() */
 877 
 878 MRI *MRIreadInfo(char *fname)
 879 {
 880 
 881   MRI *mri = NULL;
 882 
 883   mri = mri_read(fname, MRI_VOLUME_TYPE_UNKNOWN, FALSE, -1, -1);
 884 
 885   return(mri);
 886 
 887 } /* end MRIreadInfo() */
 888 
 889 /*---------------------------------------------------------------
 890   MRIreadHeader() - reads the MRI header of the given file name.
 891   If type is MRI_VOLUME_TYPE_UNKNOWN, then the type will be
 892   inferred from the file name.
 893   ---------------------------------------------------------------*/
 894 MRI *MRIreadHeader(char *fname, int type)
 895 {
 896   int usetype;
 897   MRI *mri = NULL;
 898   char modFname[STRLEN];
 899   struct stat stat_buf;
 900 
 901   usetype = type;
 902 
 903   if (!strchr(fname,DIR_SEPARATOR))
 904     {
 905       char *cwd = getcwd(NULL, 0); // posix 1 extension
 906                                    // (allocate as much space needed)
 907       if (cwd)
 908         {
 909           strcpy(modFname, cwd);
 910           strcat(modFname, "/");
 911           strcat(modFname, fname);
 912           free(cwd);
 913         }
 914       else // why fail?
 915         strcpy(modFname, fname);
 916     }
 917   else
 918     strcpy(modFname, fname);
 919 
 920   if(usetype == MRI_VOLUME_TYPE_UNKNOWN){
 921     usetype = mri_identify(modFname);
 922     if(usetype == MRI_VOLUME_TYPE_UNKNOWN)
 923       {
 924         // just check again
 925         if (stat(fname, &stat_buf) < 0)
 926           printf("ERROR: cound not find volume %s.  Does it exist?\n", fname);
 927         else
 928           printf("ERROR: could not determine type of %s\n",fname);
 929         return(NULL);
 930       }
 931   }
 932   mri = mri_read(modFname, usetype, FALSE, -1, -1);
 933 
 934   return(mri);
 935 
 936 } /* end MRIreadInfo() */
 937 
 938 int MRIwriteType(MRI *mri, char *fname, int type)
 939 {
 940   struct stat stat_buf;
 941   int error=0;
 942   char *fstem;
 943   char tmpstr[STRLEN];
 944 
 945   if(type == MRI_CORONAL_SLICE_DIRECTORY)
 946     {
 947       error = corWrite(mri, fname);
 948     }
 949   else
 950     {
 951       /* ----- all remaining types should write to
 952          a filename, not to within a directory,
 953          so check that it isn't an existing directory name we've been passed.
 954          failure to check will result in a segfault
 955          when attempting to write file data
 956          to a 'file' that is actually an existing directory ----- */
 957       if(stat(fname, &stat_buf) == 0){  // if can stat, then fname exists
 958         if(S_ISDIR(stat_buf.st_mode)){ // if is directory...
 959           errno = 0;
 960           ErrorReturn
 961             (ERROR_BADFILE,
 962              (ERROR_BADFILE,
 963               "MRIwriteType(): %s is an existing directory. (type=%d)\n"
 964               "                A filename should be specified instead.",
 965               fname, type));
 966         }
 967       }
 968     }
 969 
 970   /* ----- continue file writing... ----- */
 971 
 972   if(type == MRI_MINC_FILE)
 973     {
 974       error = mincWrite(mri, fname);
 975     }
 976   else if(type == BHDR)
 977     {
 978       fstem = bhdr_stem(fname);
 979       if(mri->type == MRI_SHORT){
 980         sprintf(tmpstr,"%s_000.bshort",fstem);
 981         error = bvolumeWrite(mri, tmpstr, MRI_SHORT);
 982       }
 983       else{
 984         sprintf(tmpstr,"%s_000.bfloat",fstem);
 985         error = bvolumeWrite(mri, tmpstr, MRI_FLOAT);
 986       }
 987       free(fstem);
 988     }
 989   else if(type == BSHORT_FILE)
 990     {
 991       error = bvolumeWrite(mri, fname, MRI_SHORT);
 992     }
 993   else if(type == BFLOAT_FILE)
 994     {
 995       error = bvolumeWrite(mri, fname, MRI_FLOAT);
 996     }
 997   else if(type == MRI_ANALYZE_FILE)
 998     {
 999       error = analyzeWrite(mri, fname);
1000     }
1001   else if(type == MRI_ANALYZE4D_FILE)
1002     {
1003       error = analyzeWrite4D(mri, fname);
1004     }
1005   else if(type == BRIK_FILE)
1006     {
1007       error = afniWrite(mri, fname);
1008     }
1009   else if(type == MRI_MGH_FILE)
1010     {
1011       error = mghWrite(mri, fname, -1);
1012     }
1013   else if(type == GDF_FILE)
1014     {
1015       error = gdfWrite(mri, fname);
1016     }
1017   else if(type == NIFTI1_FILE)
1018     {
1019       error = nifti1Write(mri, fname);
1020     }
1021   else if(type == NII_FILE) error = niiWrite(mri, fname);
1022   else if(type == GENESIS_FILE)
1023     {
1024       errno = 0;
1025       ErrorReturn
1026         (ERROR_BADPARM,
1027          (ERROR_BADPARM,
1028           "MRIwriteType(): writing of GENESIS file type not supported"));
1029     }
1030   else if(type == GE_LX_FILE)
1031     {
1032       errno = 0;
1033       ErrorReturn
1034         (ERROR_BADPARM,
1035          (ERROR_BADPARM,
1036           "MRIwriteType(): writing of GE LX file type not supported"));
1037     }
1038   else if(type == SIEMENS_FILE)
1039     {
1040       errno = 0;
1041       ErrorReturn
1042         (ERROR_BADPARM,
1043          (ERROR_BADPARM,
1044           "MRIwriteType(): writing of SIEMENS file type not supported"));
1045     }
1046   else if(type == SDT_FILE)
1047     {
1048       errno = 0;
1049       ErrorReturn
1050         (ERROR_BADPARM,
1051          (ERROR_BADPARM,
1052           "MRIwriteType(): writing of SDT file type not supported"));
1053     }
1054   else if(type == OTL_FILE)
1055     {
1056       errno = 0;
1057       ErrorReturn
1058         (ERROR_BADPARM,
1059          (ERROR_BADPARM,
1060           "MRIwriteType(): writing of OTL file type not supported"));
1061     }
1062   else if(type == RAW_FILE)
1063     {
1064       errno = 0;
1065       ErrorReturn
1066         (ERROR_BADPARM,
1067          (ERROR_BADPARM,
1068           "MRIwriteType(): writing of RAW file type not supported"));
1069     }
1070   else if(type == SIGNA_FILE)
1071     {
1072       errno = 0;
1073       ErrorReturn
1074         (ERROR_BADPARM,
1075          (ERROR_BADPARM,
1076           "MRIwriteType(): writing of SIGNA file type not supported"));
1077     }
1078   else if(type == DICOM_FILE)
1079     {
1080       errno = 0;
1081       ErrorReturn
1082         (ERROR_BADPARM,
1083          (ERROR_BADPARM,
1084           "MRIwriteType(): writing of DICOM file type not supported"));
1085     }
1086   else if(type == SIEMENS_DICOM_FILE)
1087     {
1088       errno = 0;
1089       ErrorReturn
1090         (ERROR_BADPARM,
1091          (ERROR_BADPARM,
1092           "MRIwriteType(): writing of SIEMENS DICOM file type not supported"));
1093     }
1094   else if(type == BRUKER_FILE)
1095     {
1096       errno = 0;
1097       ErrorReturn
1098         (ERROR_BADPARM,
1099          (ERROR_BADPARM,
1100           "MRIwriteType(): writing of BRUKER file type not supported"));
1101     }
1102   else if(type == XIMG_FILE)
1103     {
1104       errno = 0;
1105       ErrorReturn
1106         (ERROR_BADPARM,
1107          (ERROR_BADPARM,
1108           "MRIwriteType(): writing of XIMG file type not supported"));
1109     }
1110   else if(type == MRI_CORONAL_SLICE_DIRECTORY)
1111     {
1112       // already processed above
1113     }
1114   else
1115     {
1116       errno = 0;
1117       ErrorReturn(ERROR_BADPARM,
1118                   (ERROR_BADPARM,
1119                    "MRIwriteType(): code inconsistency "
1120                    "(file type recognized but not caught)"));
1121     }
1122 
1123   return(error);
1124 
1125 } /* end MRIwriteType() */
1126 
1127 int
1128 MRIwriteFrame(MRI *mri, char *fname, int frame)
1129 {
1130   MRI *mri_tmp ;
1131 
1132   mri_tmp =  MRIcopyFrame(mri, NULL, frame, 0) ;
1133   MRIwrite(mri_tmp, fname) ;
1134   MRIfree(&mri_tmp) ;
1135   return(NO_ERROR) ;
1136 }
1137 
1138 int MRIwrite(MRI *mri, char *fname)
1139 {
1140 
1141   int int_type = -1;
1142   int error;
1143 
1144   chklc() ;
1145   if((int_type = mri_identify(fname)) < 0)
1146     {
1147       errno = 0;
1148       ErrorReturn
1149         (ERROR_BADPARM,
1150          (ERROR_BADPARM, "unknown file type for file (%s)", fname));
1151     }
1152 
1153   error = MRIwriteType(mri, fname, int_type);
1154 
1155   return(error);
1156 
1157 } /* end MRIwrite() */
1158 
1159 
1160 /* ----- required header fields ----- */
1161 
1162 #define COR_ALL_REQUIRED 0x00001fff
1163 
1164 #define IMNR0_FLAG   0x00000001
1165 #define IMNR1_FLAG   0x00000002
1166 #define PTYPE_FLAG   0x00000004
1167 #define X_FLAG       0x00000008
1168 #define Y_FLAG       0x00000010
1169 #define THICK_FLAG   0x00000020
1170 #define PSIZ_FLAG    0x00000040
1171 #define STRTX_FLAG   0x00000080
1172 #define ENDX_FLAG    0x00000100
1173 #define STRTY_FLAG   0x00000200
1174 #define ENDY_FLAG    0x00000400
1175 #define STRTZ_FLAG   0x00000800
1176 #define ENDZ_FLAG    0x00001000
1177 
1178 /* trivially time course clean */
1179 static MRI *corRead(char *fname, int read_volume)
1180 {
1181 
1182   MRI *mri;
1183   struct stat stat_buf;
1184   char fname_use[STRLEN];
1185   char *fbase;
1186   FILE *fp;
1187   int i, j;
1188   char line[STRLEN];
1189   int imnr0, imnr1, x, y, ptype;
1190   double fov, thick, psiz, locatn; /* using floats to read creates problems
1191                                       when checking values
1192                                       (e.g. thick = 0.00100000005) */
1193   float strtx, endx, strty, endy, strtz, endz;
1194   float tr, te, ti, flip_angle ;
1195   int ras_good_flag;
1196   float x_r, x_a, x_s;
1197   float y_r, y_a, y_s;
1198   float z_r, z_a, z_s;
1199   float c_r, c_a, c_s;
1200   char xform[STRLEN];
1201   long gotten;
1202   char xform_use[STRLEN];
1203   char *cur_char;
1204   char *last_slash;
1205 
1206   /* ----- check that it is a directory we've been passed ----- */
1207   strcpy(fname_use, fname);
1208   if(stat(fname_use, &stat_buf) < 0)
1209     {
1210       errno = 0;
1211       ErrorReturn(NULL,
1212                   (ERROR_BADFILE, "corRead(): can't stat %s", fname_use));
1213     }
1214 
1215   if(!S_ISDIR(stat_buf.st_mode))
1216     {
1217       /* remove the last bit and try again */
1218       cur_char = fname_use;
1219       last_slash = cur_char;
1220       while( *(cur_char+1) != '\0' )
1221         {
1222           if(*cur_char == '/')
1223             last_slash = cur_char;
1224           cur_char++;
1225         }
1226       *last_slash = '\0';
1227       if(stat(fname_use, &stat_buf) < 0)
1228         {
1229           errno = 0;
1230           ErrorReturn
1231             (NULL,
1232              (ERROR_BADFILE, "corRead(): can't stat %s", fname_use));
1233         }
1234       if(!S_ISDIR(stat_buf.st_mode))
1235         {
1236           errno = 0;
1237           ErrorReturn
1238             (NULL,
1239              (ERROR_BADFILE, "corRead(): %s isn't a directory", fname_use));
1240         }
1241     }
1242 
1243   /* ----- copy the directory name and remove any trailing '/' ----- */
1244   fbase = &fname_use[strlen(fname_use)];
1245   if(*(fbase-1) != '/')
1246     {
1247       *fbase = '/';
1248       fbase++;
1249     }
1250 
1251   /* ----- read the header file ----- */
1252   sprintf(fbase, "COR-.info");
1253   if((fp = fopen(fname_use, "r")) == NULL)
1254     {
1255       errno = 0;
1256       ErrorReturn
1257         (NULL, (ERROR_BADFILE, "corRead(): can't open file %s", fname_use));
1258     }
1259 
1260   /* ----- defaults (a good idea for non-required values...) ----- */
1261   xform[0] = '\0';
1262   ras_good_flag = 0;
1263   x_r = x_a = x_s = 0.0;
1264   y_r = y_a = y_s = 0.0;
1265   z_r = z_a = z_s = 0.0;
1266   c_r = c_a = c_s = 0.0;
1267   flip_angle = tr = te = ti = 0.0;
1268   fov = 0.0;
1269   locatn = 0.0;
1270 
1271   gotten = 0x00;
1272 
1273   while(fgets(line, STRLEN, fp) != NULL)
1274     {
1275       if(strncmp(line, "imnr0 ", 6) == 0)
1276         {
1277           sscanf(line, "%*s %d", &imnr0);
1278           gotten = gotten | IMNR0_FLAG;
1279         }
1280       else if(strncmp(line, "imnr1 ", 6) == 0)
1281         {
1282           sscanf(line, "%*s %d", &imnr1);
1283           gotten = gotten | IMNR1_FLAG;
1284         }
1285       else if(strncmp(line, "ptype ", 6) == 0)
1286         {
1287           sscanf(line, "%*s %d", &ptype);
1288           gotten = gotten | PTYPE_FLAG;
1289         }
1290       else if(strncmp(line, "x ", 2) == 0)
1291         {
1292           sscanf(line, "%*s %d", &x);
1293           gotten = gotten | X_FLAG;
1294         }
1295       else if(strncmp(line, "y ", 2) == 0)
1296         {
1297           sscanf(line, "%*s %d", &y);
1298           gotten = gotten | Y_FLAG;
1299         }
1300       else if(strncmp(line, "fov ", 4) == 0)
1301         {
1302           sscanf(line, "%*s %lf", &fov);
1303         }
1304       else if(strncmp(line, "thick ", 6) == 0)
1305         {
1306           sscanf(line, "%*s %lf", &thick);
1307           gotten = gotten | THICK_FLAG;
1308         }
1309       else if(strncmp(line, "flip ", 5) == 0)
1310         {
1311           sscanf(line+11, "%f", &flip_angle);
1312           flip_angle = RADIANS(flip_angle) ;
1313         }
1314       else if(strncmp(line, "psiz ", 5) == 0)
1315         {
1316           sscanf(line, "%*s %lf", &psiz);
1317           gotten = gotten | PSIZ_FLAG;
1318         }
1319       else if(strncmp(line, "locatn ", 7) == 0)
1320         {
1321           sscanf(line, "%*s %lf", &locatn);
1322         }
1323       else if(strncmp(line, "strtx ", 6) == 0)
1324         {
1325           sscanf(line, "%*s %f", &strtx);
1326           gotten = gotten | STRTX_FLAG;
1327         }
1328       else if(strncmp(line, "endx ", 5) == 0)
1329         {
1330           sscanf(line, "%*s %f", &endx);
1331           gotten = gotten | ENDX_FLAG;
1332         }
1333       else if(strncmp(line, "strty ", 6) == 0)
1334         {
1335           sscanf(line, "%*s %f", &strty);
1336           gotten = gotten | STRTY_FLAG;
1337         }
1338       else if(strncmp(line, "endy ", 5) == 0)
1339         {
1340           sscanf(line, "%*s %f", &endy);
1341           gotten = gotten | ENDY_FLAG;
1342         }
1343       else if(strncmp(line, "strtz ", 6) == 0)
1344         {
1345           sscanf(line, "%*s %f", &strtz);
1346           gotten = gotten | STRTZ_FLAG;
1347         }
1348       else if(strncmp(line, "endz ", 5) == 0)
1349         {
1350           sscanf(line, "%*s %f", &endz);
1351           gotten = gotten | ENDZ_FLAG;
1352         }
1353       else if(strncmp(line, "tr ", 3) == 0)
1354         {
1355           sscanf(line, "%*s %f", &tr);
1356         }
1357       else if(strncmp(line, "te ", 3) == 0)
1358         {
1359           sscanf(line, "%*s %f", &te);
1360         }
1361       else if(strncmp(line, "ti ", 3) == 0)
1362         {
1363           sscanf(line, "%*s %f", &ti);
1364         }
1365       else if(strncmp(line, "ras_good_flag ", 14) == 0)
1366         {
1367           sscanf(line, "%*s %d", &ras_good_flag);
1368         }
1369       else if(strncmp(line, "x_ras ", 6) == 0)
1370         {
1371           sscanf(line, "%*s %f %f %f", &x_r, &x_a, &x_s);
1372         }
1373       else if(strncmp(line, "y_ras ", 6) == 0)
1374         {
1375           sscanf(line, "%*s %f %f %f", &y_r, &y_a, &y_s);
1376         }
1377       else if(strncmp(line, "z_ras ", 6) == 0)
1378         {
1379           sscanf(line, "%*s %f %f %f", &z_r, &z_a, &z_s);
1380         }
1381       else if(strncmp(line, "c_ras ", 6) == 0)
1382         {
1383           sscanf(line, "%*s %f %f %f", &c_r, &c_a, &c_s);
1384         }
1385       else if(strncmp(line, "xform", 5) == 0 ||
1386               strncmp(line, "transform", 9) == 0)
1387         {
1388           sscanf(line, "%*s %s", xform);
1389         }
1390     }
1391 
1392   fclose(fp);
1393 
1394   /* ----- check for required fields ----- */
1395   if((gotten & COR_ALL_REQUIRED) != COR_ALL_REQUIRED)
1396     {
1397       errno = 0;
1398       ErrorPrintf(ERROR_BADFILE, "missing fields in file %s:", fname_use);
1399       if(!(gotten & IMNR0_FLAG))
1400         ErrorPrintf(ERROR_BADFILE, "  imnr0 field missing");
1401       if(!(gotten & IMNR1_FLAG))
1402         ErrorPrintf(ERROR_BADFILE, "  imnr1 field missing");
1403       if(!(gotten & PTYPE_FLAG))
1404         ErrorPrintf(ERROR_BADFILE, "  ptype field missing");
1405       if(!(gotten & X_FLAG))
1406         ErrorPrintf(ERROR_BADFILE, "  x field missing");
1407       if(!(gotten & Y_FLAG))
1408         ErrorPrintf(ERROR_BADFILE, "  y field missing");
1409       if(!(gotten & THICK_FLAG))
1410         ErrorPrintf(ERROR_BADFILE, "  thick field missing");
1411       if(!(gotten & PSIZ_FLAG))
1412         ErrorPrintf(ERROR_BADFILE, "  psiz field missing");
1413       if(!(gotten & STRTX_FLAG))
1414         ErrorPrintf(ERROR_BADFILE, "  strtx field missing");
1415       if(!(gotten & ENDX_FLAG))
1416         ErrorPrintf(ERROR_BADFILE, "  endx field missing");
1417       if(!(gotten & STRTY_FLAG))
1418         ErrorPrintf(ERROR_BADFILE, "  strty field missing");
1419       if(!(gotten & ENDY_FLAG))
1420         ErrorPrintf(ERROR_BADFILE, "  endy field missing");
1421       if(!(gotten & STRTZ_FLAG))
1422         ErrorPrintf(ERROR_BADFILE, "  strtz field missing");
1423       if(!(gotten & ENDZ_FLAG))
1424         ErrorPrintf(ERROR_BADFILE, "  endz field missing");
1425       return(NULL);
1426     }
1427 
1428   /* ----- check for required but forced (constant) values ----- */
1429 
1430   if(imnr0 != 1)
1431     {
1432       printf
1433         ("warning: non-standard value for imnr0 "
1434          "(%d, usually 1) in file %s\n",
1435          imnr0, fname_use);
1436     }
1437 
1438   if(imnr1 != 256)
1439     {
1440       printf
1441         ("warning: non-standard value for imnr1 "
1442          "(%d, usually 256) in file %s\n",
1443          imnr1, fname_use);
1444     }
1445 
1446   if(ptype != 2)
1447     {
1448       printf("warning: non-standard value for ptype "
1449              "(%d, usually 2) in file %s\n",
1450              ptype, fname_use);
1451     }
1452 
1453   if(x != 256)
1454     {
1455       printf("warning: non-standard value for x "
1456              "(%d, usually 256) in file %s\n",
1457              x, fname_use);
1458     }
1459 
1460   if(y != 256)
1461     {
1462       printf("warning: non-standard value for y "
1463              "(%d, usually 256) in file %s\n",
1464              y, fname_use);
1465     }
1466 
1467   if(thick != 0.001)
1468     {
1469       printf("warning: non-standard value for thick "
1470              "(%g, usually 0.001) in file %s\n",
1471              thick, fname_use);
1472     }
1473 
1474   if(psiz != 0.001)
1475     {
1476       printf("warning: non-standard value for psiz "
1477              "(%g, usually 0.001) in file %s\n",
1478              psiz, fname_use);
1479     }
1480 
1481   /* ----- copy header information to an mri structure ----- */
1482 
1483   if(read_volume)
1484     mri = MRIalloc(x, y, imnr1 - imnr0 + 1, MRI_UCHAR);
1485   else
1486     mri = MRIallocHeader(x, y, imnr1 - imnr0 + 1, MRI_UCHAR);
1487 
1488   /* hack */
1489   /*
1490     printf("%g, %g, %g\n", x_r, x_a, x_s);
1491     printf("%g, %g, %g\n", y_r, y_a, y_s);
1492     printf("%g, %g, %g\n", z_r, z_a, z_s);
1493   */
1494   if(x_r == 0.0 && x_a == 0.0 && x_s == 0.0 && y_r == 0.0 \
1495      && y_a == 0.0 && y_s == 0.0 && z_r == 0.0 && z_a == 0.0 && z_s == 0.0)
1496     {
1497       fprintf(stderr,
1498               "----------------------------------------------------\n"
1499               "Could not find the direction cosine information.\n"
1500               "Will use the CORONAL orientation.\n"
1501               "If not suitable, please provide the information "
1502               "in COR-.info file\n"
1503               "----------------------------------------------------\n"
1504               );
1505       x_r = -1.0;
1506       y_s = -1.0;
1507       z_a = 1.0;
1508       ras_good_flag = 0;
1509     }
1510 
1511   mri->imnr0 = imnr0;
1512   mri->imnr1 = imnr1;
1513   mri->fov = (float)(fov * 1000);
1514   mri->thick = (float)(thick * 1000);
1515   mri->ps = (float)(psiz * 1000);
1516   mri->xsize = mri->ps;
1517   mri->ysize = mri->ps;
1518   mri->zsize = (float)(mri->thick);
1519   mri->xstart = strtx * 1000;
1520   mri->xend = endx * 1000;
1521   mri->ystart = strty * 1000;
1522   mri->yend = endy * 1000;
1523   mri->zstart = strtz * 1000;
1524   mri->zend = endz * 1000;
1525   strcpy(mri->fname, fname);
1526   mri->tr = tr;
1527   mri->te = te;
1528   mri->ti = ti;
1529   mri->flip_angle = flip_angle ;
1530   mri->ras_good_flag = ras_good_flag;
1531   mri->x_r = x_r;  mri->x_a = x_a;  mri->x_s = x_s;
1532   mri->y_r = y_r;  mri->y_a = y_a;  mri->y_s = y_s;
1533   mri->z_r = z_r;  mri->z_a = z_a;  mri->z_s = z_s;
1534   mri->c_r = c_r;  mri->c_a = c_a;  mri->c_s = c_s;
1535 
1536   if(strlen(xform) > 0)
1537     {
1538 
1539       if(xform[0] == '/')
1540         strcpy(mri->transform_fname, xform);
1541       else
1542         sprintf(mri->transform_fname, "%s/%s", fname, xform);
1543 
1544       strcpy(xform_use, mri->transform_fname);
1545 
1546       if(!FileExists(xform_use))
1547         {
1548 
1549           sprintf(xform_use, "%s/../transforms/talairach.xfm", fname);
1550 
1551           if(!FileExists(xform_use))
1552             printf("can't find talairach file '%s'\n", xform_use);
1553 
1554         }
1555 
1556       if(FileExists(xform_use))
1557         {
1558           if(input_transform_file(xform_use, &(mri->transform)) == NO_ERROR)
1559             {
1560               mri->linear_transform =
1561                 get_linear_transform_ptr(&mri->transform);
1562               mri->inverse_linear_transform =
1563                 get_inverse_linear_transform_ptr(&mri->transform);
1564               mri->free_transform = 1;
1565               strcpy(mri->transform_fname, xform_use);
1566               if (DIAG_VERBOSE_ON)
1567                 fprintf
1568                   (stderr,
1569                    "INFO: loaded talairach xform : %s\n",
1570                    mri->transform_fname);
1571             }
1572           else
1573             {
1574               errno = 0;
1575               ErrorPrintf
1576                 (ERROR_BAD_FILE, "error loading transform from %s", xform_use);
1577               mri->linear_transform = NULL;
1578               mri->inverse_linear_transform = NULL;
1579               mri->free_transform = 1;
1580               (mri->transform_fname)[0] = '\0';
1581             }
1582         }
1583 
1584     }
1585 
1586   if(!read_volume)
1587     return(mri);
1588 
1589   /* ----- read the data files ----- */
1590   for(i = mri->imnr0;i <= imnr1;i++)
1591     {
1592       sprintf(fbase, "COR-%03d", i);
1593       if((fp = fopen(fname_use, "r")) == NULL)
1594         {
1595           MRIfree(&mri);
1596           errno = 0;
1597           ErrorReturn
1598             (NULL,
1599              (ERROR_BADFILE, "corRead(): can't open file %s", fname_use));
1600         }
1601       for(j = 0;j < mri->height;j++)
1602         {
1603           if(fread(mri->slices[i-mri->imnr0][j], 1, mri->width, fp) <
1604              mri->width)
1605             {
1606               MRIfree(&mri);
1607               errno = 0;
1608               ErrorReturn
1609                 (NULL,
1610                  (ERROR_BADFILE,
1611                   "corRead(): error reading from file %s", fname_use));
1612             }
1613         }
1614       fclose(fp);
1615     }
1616 
1617   return(mri);
1618 
1619 } /* end corRead() */
1620 
1621 static int corWrite(MRI *mri, char *fname)
1622 {
1623 
1624   struct stat stat_buf;
1625   char fname_use[STRLEN];
1626   char *fbase;
1627   FILE *fp;
1628   int i, j;
1629   int rv;
1630 
1631   /* ----- check the mri structure for COR file compliance ----- */
1632 
1633   if(mri->slices == NULL)
1634     {
1635       errno = 0;
1636       ErrorReturn(ERROR_BADPARM, (ERROR_BADPARM,
1637                                   "corWrite(): mri structure to be "
1638                                   "written contains no voxel data"));
1639     }
1640 
1641   if(mri->imnr0 != 1)
1642     {
1643       printf
1644         ("non-standard value for imnr0 (%d, usually 1) in volume structure\n",
1645          mri->imnr0);
1646     }
1647 
1648   if(mri->imnr1 != 256)
1649     {
1650       printf
1651         ("non-standard value for imnr1 (%d, "
1652          "usually 256) in volume structure\n",
1653          mri->imnr1);
1654     }
1655 
1656   if(mri->type != MRI_UCHAR)
1657     {
1658       printf("non-standard value for type "
1659              "(%d, usually %d) in volume structure\n",
1660              mri->type, MRI_UCHAR);
1661     }
1662 
1663   if(mri->width != 256)
1664     {
1665       printf("non-standard value for width "
1666              "(%d, usually 256) in volume structure\n",
1667              mri->width);
1668     }
1669 
1670   if(mri->height != 256)
1671     {
1672       printf("non-standard value for height "
1673              "(%d, usually 256) in volume structure\n",
1674              mri->height);
1675     }
1676 
1677   if(mri->thick != 1)
1678     {
1679       printf("non-standard value for thick "
1680              "(%g, usually 1) in volume structure\n",
1681              mri->thick);
1682     }
1683 
1684   if(mri->ps != 1){
1685     printf("non-standard value for ps "
1686            "(%g, usually 1) in volume structure\n",
1687            mri->ps);
1688   }
1689 
1690   /* ----- copy the directory name and remove any trailing '/' ----- */
1691   strcpy(fname_use, fname);
1692   fbase = &fname_use[strlen(fname_use)];
1693   if(*(fbase-1) != '/')
1694     {
1695       *fbase = '/';
1696       fbase++;
1697       *fbase = '\0';
1698     }
1699 
1700   /* Create the directory */
1701   rv = mkdir(fname_use,(mode_t)-1);
1702   if(rv != 0 && errno != EEXIST){
1703     printf("ERROR: creating directory %s\n",fname_use);
1704     perror(NULL);
1705     return(1);
1706   }
1707 
1708   /* ----- check that it is a directory we've been passed ----- */
1709   if(stat(fname, &stat_buf) < 0){
1710     errno = 0;
1711     ErrorReturn
1712       (ERROR_BADFILE, (ERROR_BADFILE, "corWrite(): can't stat %s", fname));
1713   }
1714 
1715   if(!S_ISDIR(stat_buf.st_mode)){
1716     errno = 0;
1717     ErrorReturn
1718       (ERROR_BADFILE,
1719        (ERROR_BADFILE, "corWrite(): %s isn't a directory", fname));
1720   }
1721 
1722   sprintf(fbase, "COR-.info");
1723   if((fp = fopen(fname_use, "w")) == NULL)
1724     {
1725       errno = 0;
1726       ErrorReturn
1727         (ERROR_BADFILE,
1728          (ERROR_BADFILE,
1729           "corWrite(): can't open file %s for writing", fname_use));
1730     }
1731 
1732   fprintf(fp, "imnr0 %d\n", mri->imnr0);
1733   fprintf(fp, "imnr1 %d\n", mri->imnr1);
1734   fprintf(fp, "ptype %d\n", 2);
1735   fprintf(fp, "x %d\n", mri->width);
1736   fprintf(fp, "y %d\n", mri->height);
1737   fprintf(fp, "fov %g\n", mri->fov / 1000.0);
1738   fprintf(fp, "thick %g\n", mri->zsize / 1000.0); /* was xsize 11/1/01 */
1739   fprintf(fp, "psiz %g\n", mri->xsize / 1000.0);  /* was zsize 11/1/01 */
1740   fprintf(fp, "locatn %g\n", 0.0);
1741   fprintf(fp, "strtx %g\n", mri->xstart / 1000.0);
1742   fprintf(fp, "endx %g\n", mri->xend / 1000.0);
1743   fprintf(fp, "strty %g\n", mri->ystart / 1000.0);
1744   fprintf(fp, "endy %g\n", mri->yend / 1000.0);
1745   fprintf(fp, "strtz %g\n", mri->zstart / 1000.0);
1746   fprintf(fp, "endz %g\n", mri->zend / 1000.0);
1747   fprintf(fp, "tr %f\n", mri->tr);
1748   fprintf(fp, "te %f\n", mri->te);
1749   fprintf(fp, "ti %f\n", mri->ti);
1750   fprintf(fp, "flip angle %f\n", DEGREES(mri->flip_angle));
1751   fprintf(fp, "ras_good_flag %d\n", mri->ras_good_flag);
1752   fprintf(fp, "x_ras %f %f %f\n", mri->x_r, mri->x_a, mri->x_s);
1753   fprintf(fp, "y_ras %f %f %f\n", mri->y_r, mri->y_a, mri->y_s);
1754   fprintf(fp, "z_ras %f %f %f\n", mri->z_r, mri->z_a, mri->z_s);
1755   fprintf(fp, "c_ras %f %f %f\n", mri->c_r, mri->c_a, mri->c_s);
1756   if(strlen(mri->transform_fname) > 0)
1757     fprintf(fp, "xform %s\n", mri->transform_fname);
1758 
1759   fclose(fp);
1760 
1761   for(i = mri->imnr0;i <= mri->imnr1;i++)
1762     {
1763       sprintf(fbase, "COR-%03d", i);
1764       if((fp = fopen(fname_use, "w")) == NULL)
1765         {
1766           errno = 0;
1767           ErrorReturn
1768             (ERROR_BADFILE,
1769              (ERROR_BADFILE,
1770               "corWrite(): can't open file %s for writing", fname_use));
1771         }
1772       for(j = 0;j < mri->height;j++)
1773         {
1774           if(fwrite(mri->slices[i-mri->imnr0][j], 1, mri->width, fp) <
1775              mri->width)
1776             {
1777               fclose(fp);
1778               errno = 0;
1779               ErrorReturn
1780                 (ERROR_BADFILE,
1781                  (ERROR_BADFILE,
1782                   "corWrite(): error writing to file %s ", fname_use));
1783             }
1784         }
1785       fclose(fp);
1786     }
1787 
1788   return(NO_ERROR);
1789 
1790 } /* end corWrite() */
1791 
1792 static MRI *siemensRead(char *fname, int read_volume_flag)
1793 {
1794 
1795   int file_n, n_low, n_high;
1796   char fname_use[STRLEN];
1797   MRI *mri;
1798   FILE *fp;
1799   char *c, *c2;
1800   short rows, cols;
1801   int n_slices;
1802   double d, d2;
1803   double im_c_r, im_c_a, im_c_s;
1804   int i, j;
1805   int n_files, base_raw_matrix_size, number_of_averages;
1806   int mosaic_size;
1807   int mosaic;
1808   int mos_r, mos_c;
1809   char pulse_sequence_name[STRLEN], ps2[STRLEN];
1810   int n_t;
1811   int n_dangling_images, n_full_mosaics, mosaics_per_volume;
1812   int br, bc;
1813   MRI *mri_raw;
1814   int t, s;
1815   int slice_in_mosaic;
1816   int file;
1817   char ima[4];
1818   IMAFILEINFO *ifi;
1819 
1820   /* ----- stop compiler complaints ----- */
1821   mri = NULL;
1822   mosaic_size = 0;
1823 
1824 
1825   ifi = imaLoadFileInfo(fname);
1826   if(ifi == NULL){
1827     printf("ERROR: siemensRead(): %s\n",fname);
1828     return(NULL);
1829   }
1830 
1831   strcpy(fname_use, fname);
1832 
1833   /* ----- point to ".ima" ----- */
1834   c = fname_use + (strlen(fname_use) - 4);
1835 
1836   if(c < fname_use)
1837     {
1838       errno = 0;
1839       ErrorReturn
1840         (NULL,
1841          (ERROR_BADPARM,
1842           "siemensRead(): bad file name %s (must end in '.ima' or '.IMA')",
1843           fname_use));
1844     }
1845   if(strcmp(".ima", c) == 0)
1846     sprintf(ima, "ima");
1847   else if(strcmp(".IMA", c) == 0)
1848     sprintf(ima, "IMA");
1849   else
1850     {
1851       errno = 0;
1852       ErrorReturn
1853         (NULL,
1854          (ERROR_BADPARM,
1855           "siemensRead(): bad file name %s (must end in '.ima' or '.IMA')",
1856           fname_use));
1857     }
1858 
1859   c2 = c;
1860   for(c--;isdigit((int)(*c));c--);
1861   c++;
1862 
1863   /* ----- c now points to the first digit in the last number set
1864      (e.g. to the "5" in 123-4-567.ima) ----- */
1865 
1866   /* ----- count down and up from this file --
1867      max and min image number within the series ----- */
1868   *c2 = '\0';
1869   file_n = atol(c);
1870   *c2 = '.';
1871 
1872   if(!FileExists(fname_use))
1873     {
1874       errno = 0;
1875       ErrorReturn
1876         (NULL,
1877          (ERROR_BADFILE, "siemensRead(): file %s doesn't exist", fname_use));
1878     }
1879 
1880   /* --- get the low image number --- */
1881   n_low = file_n - 1;
1882   sprintf(c, "%d.%s", n_low, ima);
1883   while(FileExists(fname_use))
1884     {
1885       n_low--;
1886       sprintf(c, "%d.%s", n_low, ima);
1887     }
1888   n_low++;
1889 
1890   /* --- get the high image number --- */
1891   n_high = file_n + 1;
1892   sprintf(c, "%d.%s", n_high, ima);
1893   while(FileExists(fname_use))
1894     {
1895       n_high++;
1896       sprintf(c, "%d.%s", n_high, ima);
1897     }
1898   n_high--;
1899 
1900   n_files = n_high - n_low + 1;
1901 
1902   sprintf(c, "%d.%s", n_low, ima);
1903   if((fp = fopen(fname_use, "r")) == NULL)
1904     {
1905       errno = 0;
1906       ErrorReturn
1907         (NULL,
1908          (ERROR_BADFILE,
1909           "siemensRead(): can't open file %s (low = %d, this = %d, high = %d)",
1910           fname_use, n_low, file_n, n_high));
1911     }
1912 
1913   fseek(fp, 4994, SEEK_SET);
1914   fread(&rows, 2, 1, fp);
1915   rows = orderShortBytes(rows);
1916   fseek(fp, 4996, SEEK_SET);
1917   fread(&cols, 2, 1, fp);
1918   cols = orderShortBytes(cols);
1919   fseek(fp, 4004, SEEK_SET);
1920   fread(&n_slices, 4, 1, fp);
1921   n_slices = orderIntBytes(n_slices);
1922   if (n_slices==0)
1923     {
1924       errno = 0;
1925       ErrorReturn
1926         (NULL,
1927          (ERROR_BADFILE,
1928           "\n\nPlease try with the option '-it siemens_dicom'.\n "
1929           "The handling failed assuming the old siemens format.\n"))
1930         }
1931   fseek(fp, 2864, SEEK_SET);
1932   fread(&base_raw_matrix_size, 4, 1, fp);
1933   base_raw_matrix_size = orderIntBytes(base_raw_matrix_size);
1934   fseek(fp, 1584, SEEK_SET);
1935   fread(&number_of_averages, 4, 1, fp);
1936   number_of_averages = orderIntBytes(number_of_averages);
1937   memset(pulse_sequence_name, 0x00, STRLEN);
1938   fseek(fp, 3009, SEEK_SET);
1939   fread(&pulse_sequence_name, 1, 65, fp);
1940 
1941   /* --- scout --- */
1942   strcpy(ps2, pulse_sequence_name);
1943   StrLower(ps2);
1944   if(strstr(ps2, "scout") != NULL)
1945     {
1946       errno = 0;
1947       ErrorReturn
1948         (NULL,
1949          (ERROR_BADPARM,
1950           "siemensRead(): series appears to be a scout "
1951           "(sequence file name is %s)", pulse_sequence_name));
1952     }
1953 
1954   /* --- structural --- */
1955   if(n_slices == 1 && ! ifi->IsMosaic)
1956     {
1957       n_slices = n_files;
1958       n_t = 1;
1959       if(base_raw_matrix_size != rows || base_raw_matrix_size != cols)
1960         {
1961           errno = 0;
1962           ErrorReturn
1963             (NULL,
1964              (ERROR_BADPARM, "siemensRead(): bad file/base matrix sizes"));
1965         }
1966       mos_r = mos_c = 1;
1967       mosaic_size = 1;
1968     }
1969   else
1970     {
1971 
1972       if(rows % base_raw_matrix_size != 0)
1973         {
1974           errno = 0;
1975           ErrorReturn
1976             (NULL,
1977              (ERROR_BADPARM, "siemensRead(): file rows (%hd) not"
1978               " divisible by image rows (%d)", rows, base_raw_matrix_size));
1979         }
1980       if(cols % base_raw_matrix_size != 0)
1981         {
1982           errno = 0;
1983           ErrorReturn
1984             (NULL,
1985              (ERROR_BADPARM,
1986               "siemensRead(): file cols (%hd)"
1987               " not divisible by image cols (%d)",
1988               cols, base_raw_matrix_size));
1989         }
1990 
1991       mos_r = rows / base_raw_matrix_size;
1992       mos_c = cols / base_raw_matrix_size;
1993       mosaic_size = mos_r * mos_c;
1994 
1995       n_dangling_images = n_slices % mosaic_size;
1996       n_full_mosaics = (n_slices - n_dangling_images) / mosaic_size;
1997 
1998       mosaics_per_volume = n_full_mosaics + (n_dangling_images == 0 ? 0 : 1);
1999 
2000       if(n_files % mosaics_per_volume != 0)
2001         {
2002           errno = 0;
2003           ErrorReturn(NULL, (ERROR_BADPARM, "siemensRead(): files in volume "
2004                              "(%d) not divisible by mosaics per volume (%d)",
2005                              n_files, mosaics_per_volume));
2006         }
2007 
2008       n_t = n_files / mosaics_per_volume;
2009 
2010     }
2011 
2012   if(read_volume_flag)
2013     mri = MRIallocSequence
2014       (base_raw_matrix_size, base_raw_matrix_size, n_slices, MRI_SHORT, n_t);
2015   else
2016     {
2017       mri = MRIallocHeader
2018         (base_raw_matrix_size, base_raw_matrix_size, n_slices, MRI_SHORT);
2019       mri->nframes = n_t;
2020     }
2021 
2022   /* --- pixel sizes --- */
2023   /* --- mos_r and mos_c factors are strange, but they're there... --- */
2024   fseek(fp, 5000, SEEK_SET);
2025   fread(&d, 8, 1, fp);
2026   mri->xsize = mos_r * orderDoubleBytes(d);
2027   fseek(fp, 5008, SEEK_SET);
2028   fread(&d, 8, 1, fp);
2029   mri->ysize = mos_c * orderDoubleBytes(d);
2030 
2031   /* --- slice distance factor --- */
2032   fseek(fp, 4136, SEEK_SET);
2033   fread(&d, 8, 1, fp);
2034   d = orderDoubleBytes(d);
2035   if(d == -19222) /* undefined (Siemens code) -- I assume this to mean 0 */
2036     d = 0.0;
2037   /* --- slice thickness --- */
2038   fseek(fp, 1544, SEEK_SET);
2039   fread(&d2, 8, 1, fp);
2040   d2 = orderDoubleBytes(d2);
2041   /* --- distance between slices --- */
2042   mri->zsize = (1.0 + d) * d2;
2043 
2044   /* --- field of view (larger of height, width fov) --- */
2045   fseek(fp, 3744, SEEK_SET);
2046   fread(&d, 8, 1, fp);
2047   d = orderDoubleBytes(d);
2048   fseek(fp, 3752, SEEK_SET);
2049   fread(&d2, 8, 1, fp);
2050   d2 = orderDoubleBytes(d);
2051   mri->fov = (d > d2 ? d : d2);
2052 
2053   mri->thick = mri->zsize;
2054   mri->ps = mri->xsize;
2055 
2056   strcpy(mri->fname, fname);
2057 
2058   mri->location = 0.0;
2059 
2060   fseek(fp, 2112, SEEK_SET) ;
2061   mri->flip_angle = RADIANS(freadDouble(fp)) ;  /* was in degrees */
2062 
2063   fseek(fp, 1560, SEEK_SET);
2064   fread(&d, 8, 1, fp);
2065   mri->tr = orderDoubleBytes(d);
2066   fseek(fp, 1568, SEEK_SET);
2067   fread(&d, 8, 1, fp);
2068   mri->te = orderDoubleBytes(d);
2069   fseek(fp, 1576, SEEK_SET);
2070   fread(&d, 8, 1, fp);
2071   mri->ti = orderDoubleBytes(d);
2072 
2073   fseek(fp, 3792, SEEK_SET);
2074   fread(&d, 8, 1, fp);  mri->z_r = -orderDoubleBytes(d);
2075   fread(&d, 8, 1, fp);  mri->z_a =  orderDoubleBytes(d);
2076   fread(&d, 8, 1, fp);  mri->z_s = -orderDoubleBytes(d);
2077 
2078   fseek(fp, 3832, SEEK_SET);
2079   fread(&d, 8, 1, fp);  mri->x_r = -orderDoubleBytes(d);
2080   fread(&d, 8, 1, fp);  mri->x_a =  orderDoubleBytes(d);
2081   fread(&d, 8, 1, fp);  mri->x_s = -orderDoubleBytes(d);
2082 
2083   fseek(fp, 3856, SEEK_SET);
2084   fread(&d, 8, 1, fp);  mri->y_r = -orderDoubleBytes(d);
2085   fread(&d, 8, 1, fp);  mri->y_a =  orderDoubleBytes(d);
2086   fread(&d, 8, 1, fp);  mri->y_s = -orderDoubleBytes(d);
2087 
2088   fseek(fp, 3768, SEEK_SET);
2089   fread(&im_c_r, 8, 1, fp);  im_c_r = -orderDoubleBytes(im_c_r);
2090   fread(&im_c_a, 8, 1, fp);  im_c_a =  orderDoubleBytes(im_c_a);
2091   fread(&im_c_s, 8, 1, fp);  im_c_s = -orderDoubleBytes(im_c_s);
2092 
2093   mri->c_r = im_c_r - (mosaic_size - 1) * mri->z_r * mri->zsize + \
2094     ((mri->depth - 1.0) / 2.0) * mri->z_r * mri->zsize;
2095   mri->c_a = im_c_a - (mosaic_size - 1) * mri->z_a * mri->zsize + \
2096     ((mri->depth - 1.0) / 2.0) * mri->z_a * mri->zsize;
2097   mri->c_s = im_c_s - (mosaic_size - 1) * mri->z_s * mri->zsize + \
2098     ((mri->depth - 1.0) / 2.0) * mri->z_s * mri->zsize;
2099 
2100   mri->ras_good_flag = 1;
2101 
2102   fseek(fp, 3760, SEEK_SET);
2103   fread(&i, 4, 1, fp);
2104   i = orderIntBytes(i);
2105 
2106 #if 0
2107   if(i == 1 || i == 2)
2108     mri->slice_direction = MRI_HORIZONTAL;
2109   else if(i == 3 || i == 5)
2110     mri->slice_direction = MRI_CORONAL;
2111   else if(i == 4 || i == 6)
2112     mri->slice_direction = MRI_SAGITTAL;
2113   else
2114 #endif
2115     if (i < 1 || i > 6)
2116       {
2117         errno = 0;
2118         ErrorReturn
2119           (NULL,
2120            (ERROR_BADFILE,
2121             "siemensRead(): bad slice direction (%d) in file %s",
2122             i, fname_use));
2123       }
2124 
2125   mri->xstart = -mri->width * mri->xsize / 2.0;
2126   mri->xend = -mri->xstart;
2127   mri->ystart = -mri->height * mri->ysize / 2.0;
2128   mri->yend = -mri->ystart;
2129   mri->zstart = -mri->depth * mri->zsize / 2.0;
2130   mri->zend = -mri->zstart;
2131 
2132   /*
2133     printf("%d, %d; %d, %hd, %hd; %d\n", n_files, number_of_averages,
2134     base_raw_matrix_size, rows, cols,
2135     slices);
2136   */
2137   /*
2138     rows, cols, brms, mosaic i, j, mosaic size, n slices, n files, n_t
2139   */
2140   fclose(fp);
2141 
2142   mri->imnr0 = 1;
2143   mri->imnr1 = mri->depth;
2144   /*
2145     printf("%d, %d, %d, %d\n",
2146     mri->width, mri->height, mri->depth, mri->nframes);
2147   */
2148   if(read_volume_flag)
2149     {
2150 
2151       mri_raw = MRIalloc(rows, cols, n_files, MRI_SHORT);
2152 
2153       for(file_n = n_low;file_n <= n_high;file_n++)
2154         {
2155 
2156           sprintf(c, "%d.%s", file_n, ima);
2157           if((fp = fopen(fname_use, "r")) == NULL)
2158             {
2159               MRIfree(&mri);
2160               errno = 0;
2161               ErrorReturn(NULL, (ERROR_BADFILE,
2162                                  "siemensRead(): can't open file %s "
2163                                  "(low = %d, this = %d, high = %d)",
2164                                  fname_use, n_low, file_n, n_high));
2165             }
2166 
2167           fseek(fp, 6144, SEEK_SET);
2168 
2169           for(i = 0;i < rows;i++)
2170             {
2171               fread(&MRISvox(mri_raw, 0, i, file_n - n_low),
2172                     sizeof(short), cols, fp);
2173 #if (BYTE_ORDER == LITTLE_ENDIAN)
2174               swab(&MRISvox(mri_raw, 0, i, file_n - n_low), \
2175                    &MRISvox(mri_raw, 0, i, file_n - n_low),
2176                    sizeof(short) * cols);
2177 #endif
2178             }
2179 
2180           fclose(fp);
2181 
2182         }
2183 
2184       for(t = 0;t < mri->nframes;t++)
2185         {
2186           for(s = 0;s < mri->depth;s++)
2187             {
2188               slice_in_mosaic = s % mosaic_size;
2189               mosaic = (s - slice_in_mosaic) / mosaic_size;
2190               file = mri->nframes * mosaic + t;
2191               /*
2192                 printf("s, t = %d, %d; f, sm = %d, %d\n",
2193                 s, t, file, slice_in_mosaic);
2194               */
2195               bc = slice_in_mosaic % mos_r;
2196               br = (slice_in_mosaic - bc) / mos_r;
2197 
2198               for(i = 0;i < mri->width;i++)
2199                 {
2200                   for(j = 0;j < mri->height;j++)
2201                     {
2202                       MRISseq_vox(mri, i, j, s, t) = \
2203                         MRISvox
2204                         (mri_raw, mri->width *
2205                          bc + i, mri->height * br + j, file);
2206                     }
2207                 }
2208 
2209             }
2210         }
2211 
2212       MRIfree(&mri_raw);
2213 
2214     }
2215 
2216   return(mri);
2217 
2218 } /* end siemensRead() */
2219 /*-----------------------------------------------------------*/
2220 static MRI *mincRead(char *fname, int read_volume)
2221 {
2222   // Real wx, wy, wz;
2223   MRI *mri;
2224   Volume vol;
2225   VIO_Status status;
2226   char *dim_names[4];
2227   int dim_sizes[4];
2228   int ndims;
2229   int dtype;
2230   volume_input_struct input_info;
2231   Real separations[4];
2232   Real voxel[4];
2233   Real worldr, worlda, worlds;
2234   Real val;
2235   int i, j, k, t;
2236   float xfov, yfov, zfov;
2237   Real f;
2238   BOOLEAN sflag = TRUE ;
2239   Transform *pVox2WorldLin;
2240   General_transform *pVox2WorldGen;
2241 
2242   /* ----- read the volume ----- */
2243 
2244   /*   we no longer much around axes and thus */
2245   /*   it is safe to read in the standard way    */
2246   dim_names[0] = MIxspace;
2247   dim_names[1] = MIyspace;
2248   dim_names[2] = MIzspace;
2249   dim_names[3] = MItime;
2250 
2251 #if 0
2252   dim_names[0] = MIzspace;
2253   dim_names[1] = MIyspace;
2254   dim_names[2] = MIxspace;
2255   dim_names[3] = MItime;
2256 #endif
2257 
2258   if(!FileExists(fname))
2259     {
2260       errno = 0;
2261       ErrorReturn(NULL, (ERROR_BADFILE,
2262                          "mincRead(): can't find file %s", fname));
2263     }
2264 
2265   status = start_volume_input(fname, 0, dim_names, NC_UNSPECIFIED, 0, 0, 0,
2266                               TRUE, &vol, NULL, &input_info);
2267 
2268   if (Gdiag & DIAG_VERBOSE_ON && DIAG_SHOW){
2269     printf("status = %d\n", status);
2270     printf("n_dimensions = %d\n", get_volume_n_dimensions(vol));
2271     printf("nc_data_type = %d\n", vol->nc_data_type);
2272   }
2273 
2274   if(status != OK){
2275     errno = 0;
2276     ErrorReturn(NULL, (ERROR_BADPARM, "mincRead(): error reading "
2277                        "volume from file %s", fname));
2278   }
2279 
2280   /* ----- check the number of dimensions ----- */
2281   ndims = get_volume_n_dimensions(vol);
2282   if(ndims != 3 && ndims != 4){
2283     errno = 0;
2284     ErrorReturn(NULL, (ERROR_BADPARM, "mincRead(): %d dimensions "
2285                        "in file; expecting 3 or 4", ndims));
2286   }
2287 
2288   /* ----- get the dimension sizes ----- */
2289   get_volume_sizes(vol, dim_sizes);
2290 
2291   /* --- one time point if there are only three dimensions in the file --- */
2292   if(ndims == 3) dim_sizes[3] = 1;
2293 
2294   if ((Gdiag & DIAG_SHOW) && DIAG_VERBOSE_ON)
2295     printf("DimSizes: %d, %d, %d, %d, %d\n", ndims, dim_sizes[0],
2296            dim_sizes[1], dim_sizes[2], dim_sizes[3]);
2297   if ((Gdiag & DIAG_SHOW) && DIAG_VERBOSE_ON)
2298     printf("DataType: %d\n", vol->nc_data_type);
2299 
2300   dtype = get_volume_nc_data_type(vol, &sflag) ;
2301   dtype = orderIntBytes(vol->nc_data_type) ;
2302 
2303   /* ----- get the data type ----- */
2304   if(vol->nc_data_type == NC_BYTE || vol->nc_data_type == NC_CHAR)
2305     dtype = MRI_UCHAR;
2306   else if(vol->nc_data_type == NC_SHORT)
2307     dtype = MRI_SHORT;
2308   else if(vol->nc_data_type == NC_LONG)
2309     dtype = MRI_LONG;
2310   else if(vol->nc_data_type == NC_FLOAT || vol->nc_data_type == NC_DOUBLE)
2311     dtype = MRI_FLOAT;
2312   else
2313     {
2314       errno = 0;
2315       ErrorReturn(NULL, (ERROR_BADPARM, "mincRead(): bad data type "
2316                          "(%d) in input file %s", vol->nc_data_type, fname));
2317     }
2318 
2319   /* ----- allocate the mri structure ----- */
2320   if(read_volume)
2321     mri = MRIallocSequence(dim_sizes[0], dim_sizes[1], dim_sizes[2],
2322                            dtype, dim_sizes[3]);
2323   else{
2324     mri = MRIallocHeader(dim_sizes[0], dim_sizes[1], dim_sizes[2], dtype);
2325     mri->nframes = dim_sizes[3];
2326   }
2327 
2328   /* ----- set up the mri structure ----- */
2329   get_volume_separations(vol, separations);
2330   mri->xsize = fabs(separations[0]);
2331   mri->ysize = fabs(separations[1]);
2332   mri->zsize = fabs(separations[2]);
2333   mri->ps    = mri->xsize;
2334   mri->thick = mri->zsize;
2335 
2336   mri->x_r = vol->direction_cosines[0][0];
2337   mri->x_a = vol->direction_cosines[0][1];
2338   mri->x_s = vol->direction_cosines[0][2];
2339 
2340   mri->y_r = vol->direction_cosines[1][0];
2341   mri->y_a = vol->direction_cosines[1][1];
2342   mri->y_s = vol->direction_cosines[1][2];
2343 
2344   mri->z_r = vol->direction_cosines[2][0];
2345   mri->z_a = vol->direction_cosines[2][1];
2346   mri->z_s = vol->direction_cosines[2][2];
2347 
2348   if(separations[0] < 0){
2349     mri->x_r = -mri->x_r;  mri->x_a = -mri->x_a;  mri->x_s = -mri->x_s;
2350   }
2351   if(separations[1] < 0){
2352     mri->y_r = -mri->y_r;  mri->y_a = -mri->y_a;  mri->y_s = -mri->y_s;
2353   }
2354   if(separations[2] < 0){
2355     mri->z_r = -mri->z_r;  mri->z_a = -mri->z_a;  mri->z_s = -mri->z_s;
2356   }
2357 
2358   voxel[0] = (mri->width) / 2.0;
2359   voxel[1] = (mri->height) / 2.0;
2360   voxel[2] = (mri->depth) / 2.0;
2361   voxel[3] = 0.0;
2362   convert_voxel_to_world(vol, voxel, &worldr, &worlda, &worlds);
2363   mri->c_r = worldr;
2364   mri->c_a = worlda;
2365   mri->c_s = worlds;
2366 
2367   mri->ras_good_flag = 1;
2368 
2369   mri->xend = mri->xsize * mri->width / 2.0;   mri->xstart = -mri->xend;
2370   mri->yend = mri->ysize * mri->height / 2.0;  mri->ystart = -mri->yend;
2371   mri->zend = mri->zsize * mri->depth / 2.0;   mri->zstart = -mri->zend;
2372 
2373   xfov = mri->xend - mri->xstart;
2374   yfov = mri->yend - mri->ystart;
2375   zfov = mri->zend - mri->zstart;
2376 
2377   mri->fov = ( xfov > yfov ? (xfov > zfov ? xfov : zfov ) :
2378                (yfov > zfov ? yfov : zfov ) );
2379 
2380   strcpy(mri->fname, fname);
2381 
2382   //////////////////////////////////////////////////////////////////////////
2383   // test transform their way and our way:
2384   // MRIvoxelToWorld(mri, voxel[0], voxel[1], voxel[2], &wx, &wy, &wz);
2385   // printf("MNI calculated %.2f, %.2f, %.2f
2386   //     vs. MRIvoxelToWorld: %.2f, %.2f, %.2f\n",
2387   //     worldr, worlda, worlds, wx, wy, wz);
2388 
2389   /* ----- copy the data from the file to the mri structure ----- */
2390   if(read_volume){
2391 
2392     while(input_more_of_volume(vol, &input_info, &f));
2393 
2394     for(i = 0;i < mri->width;i++) {
2395       for(j = 0;j < mri->height;j++) {
2396         for(k = 0;k < mri->depth;k++) {
2397           for(t = 0;t < mri->nframes;t++) {
2398             val = get_volume_voxel_value(vol, i, j, k, t, 0);
2399             if(mri->type == MRI_UCHAR)
2400               MRIseq_vox(mri, i, j, k, t) = (unsigned char)val;
2401             if(mri->type == MRI_SHORT)
2402               MRISseq_vox(mri, i, j, k, t) = (short)val;
2403             if(mri->type == MRI_LONG)
2404               MRILseq_vox(mri, i, j, k, t) = (long)val;
2405             if(mri->type == MRI_FLOAT)
2406               MRIFseq_vox(mri, i, j, k, t) = (float)val;
2407           }
2408         }
2409       }
2410     }
2411   }
2412 
2413   pVox2WorldGen = get_voxel_to_world_transform(vol);
2414   pVox2WorldLin = get_linear_transform_ptr(pVox2WorldGen);
2415   if ((Gdiag & DIAG_SHOW) && DIAG_VERBOSE_ON)
2416     {
2417       printf("MINC Linear Transform\n");
2418       for(i=0;i<4;i++){
2419         for(j=0;j<4;j++) printf("%7.4f ",pVox2WorldLin->m[j][i]);
2420         printf("\n");
2421       }
2422     }
2423 
2424   delete_volume_input(&input_info);
2425   delete_volume(vol);
2426 
2427 
2428   return(mri);
2429 
2430 } /* end mincRead() */
2431 #if 0
2432 /*-----------------------------------------------------------*/
2433 static MRI *mincRead2(char *fname, int read_volume)
2434 {
2435 
2436   MRI *mri;
2437   Volume vol;
2438   VIO_Status status;
2439   char *dim_names[4];
2440   int dim_sizes[4];
2441   int ndims;
2442   int dtype;
2443   volume_input_struct input_info;
2444   Real separations[4];
2445   Real voxel[4];
2446   Real worldr, worlda, worlds;
2447   Real val;
2448   int i, j, k, t;
2449   float xfov, yfov, zfov;
2450   Real f;
2451   BOOLEAN sflag = TRUE ;
2452   MATRIX *T;
2453   Transform *pVox2WorldLin;
2454   General_transform *pVox2WorldGen;
2455 
2456   /* Make sure file exists */
2457   if(!FileExists(fname)){
2458     errno = 0;
2459     ErrorReturn(NULL, (ERROR_BADFILE,
2460                        "mincRead(): can't find file %s", fname));
2461   }
2462 
2463   /* Specify read-in order */
2464   dim_names[0] = MIxspace; /* cols */
2465   dim_names[1] = MIzspace; /* rows */
2466   dim_names[2] = MIyspace; /* slices */
2467   dim_names[3] = MItime;   /* time */
2468 
2469   /* Read the header info into vol. input_info needed for further reads */
2470   status = start_volume_input(fname, 0, dim_names, NC_UNSPECIFIED, 0, 0, 0,
2471                               TRUE, &vol, NULL, &input_info);
2472 
2473   if (Gdiag & DIAG_VERBOSE_ON && DIAG_SHOW){
2474     printf("status = %d\n", status);
2475     printf("n_dimensions = %d\n", get_volume_n_dimensions(vol));
2476     printf("nc_data_type = %d\n", vol->nc_data_type);
2477   }
2478 
2479   if(status != OK){
2480     errno = 0;
2481     ErrorReturn(NULL, (ERROR_BADPARM, "mincRead(): error reading "
2482                        "volume from file %s", fname));
2483   }
2484 
2485   /* ----- check the number of dimensions ----- */
2486   ndims = get_volume_n_dimensions(vol);
2487   if(ndims != 3 && ndims != 4){
2488     errno = 0;
2489     ErrorReturn(NULL, (ERROR_BADPARM, "mincRead(): %d dimensions "
2490                        "in file; expecting 3 or 4", ndims));
2491   }
2492 
2493   /* ----- get the dimension sizes ----- */
2494   get_volume_sizes(vol, dim_sizes);
2495 
2496   /* --- one time point if there are only three dimensions in the file --- */
2497   if(ndims == 3) dim_sizes[3] = 1;
2498 
2499   dtype = get_volume_nc_data_type(vol, &sflag) ;
2500   dtype = orderIntBytes(vol->nc_data_type) ;
2501   get_volume_separations(vol, separations);
2502 
2503   for(i=0;i<4;i++)
2504     printf("%d %s %3d  %7.3f %6.4f %6.4f %6.4f \n",
2505            i,dim_names[i],dim_sizes[i],separations[i],
2506            vol->direction_cosines[i][0],vol->direction_cosines[i][1],
2507            vol->direction_cosines[i][2]);
2508   if ((Gdiag & DIAG_SHOW) && DIAG_VERBOSE_ON)
2509     printf("DataType: %d\n", vol->nc_data_type);
2510 
2511   /* Translate data type to that of mri structure */
2512   switch(vol->nc_data_type){
2513   case NC_BYTE:   dtype = MRI_UCHAR; break;
2514   case NC_CHAR:   dtype = MRI_UCHAR; break;
2515   case NC_SHORT:  dtype = MRI_SHORT; break;
2516   case NC_LONG:   dtype = MRI_LONG;  break;
2517   case NC_FLOAT:  dtype = MRI_FLOAT; break;
2518   case NC_DOUBLE: dtype = MRI_FLOAT; break;
2519   default:
2520     errno = 0;
2521     ErrorReturn(NULL, (ERROR_BADPARM, "mincRead(): bad data type "
2522                        "(%d) in input file %s", vol->nc_data_type, fname));
2523     break;
2524   }
2525 
2526   /* ----- allocate the mri structure ----- */
2527   if(read_volume)
2528     mri = MRIallocSequence(dim_sizes[0], dim_sizes[1], dim_sizes[2],
2529                            dtype, dim_sizes[3]);
2530   else{
2531     mri = MRIallocHeader(dim_sizes[0], dim_sizes[1], dim_sizes[2], dtype);
2532     mri->nframes = dim_sizes[3];
2533   }
2534 
2535   /* ----- set up the mri structure ----- */
2536   get_volume_separations(vol, separations);
2537   mri->xsize = fabs(separations[0]); /* xsize = col   resolution */
2538   mri->ysize = fabs(separations[1]); /* ysize = row   resolution */
2539   mri->zsize = fabs(separations[2]); /* zsize = slice resolution */
2540   mri->ps    = mri->xsize;
2541   mri->thick = mri->zsize;
2542 
2543   /* column direction cosines */
2544   mri->x_r = vol->direction_cosines[0][0];
2545   mri->x_a = vol->direction_cosines[0][1];
2546   mri->x_s = vol->direction_cosines[0][2];
2547 
2548   /* row direction cosines */
2549   mri->y_r = vol->direction_cosines[1][0];
2550   mri->y_a = vol->direction_cosines[1][1];
2551   mri->y_s = vol->direction_cosines[1][2];
2552 
2553   /* slice direction cosines */
2554   mri->z_r = vol->direction_cosines[2][0];
2555   mri->z_a = vol->direction_cosines[2][1];
2556   mri->z_s = vol->direction_cosines[2][2];
2557 
2558   if(separations[0] < 0){
2559     mri->x_r = -mri->x_r;  mri->x_a = -mri->x_a;  mri->x_s = -mri->x_s;
2560   }
2561   if(separations[1] < 0){
2562     mri->y_r = -mri->y_r;  mri->y_a = -mri->y_a;  mri->y_s = -mri->y_s;
2563   }
2564   if(separations[2] < 0){
2565     mri->z_r = -mri->z_r;  mri->z_a = -mri->z_a;  mri->z_s = -mri->z_s;
2566   }
2567 
2568   /* Get center point */       // don't.  our convention is different
2569   voxel[0] = (mri->width)/2.;  // (mri->width  - 1) / 2.0;
2570   voxel[1] = (mri->height)/2.; // (mri->height - 1) / 2.0;
2571   voxel[2] = (mri->depth)/2.;  //(mri->depth  - 1) / 2.0;
2572   voxel[3] = 0.0;
2573   convert_voxel_to_world(vol, voxel, &worldr, &worlda, &worlds);
2574   mri->c_r = worldr;
2575   mri->c_a = worlda;
2576   mri->c_s = worlds;
2577   printf("Center Voxel: %7.3f %7.3f %7.3f\n",voxel[0],voxel[1],voxel[2]);
2578   printf("Center World: %7.3f %7.3f %7.3f\n",mri->c_r,mri->c_a,mri->c_s);
2579 
2580   mri->ras_good_flag = 1;
2581 
2582   mri->xend = mri->xsize * mri->width / 2.0; mri->xstart = -mri->xend;
2583   mri->yend = mri->ysize * mri->height/ 2.0; mri->ystart = -mri->yend;
2584   mri->zend = mri->zsize * mri->depth / 2.0; mri->zstart = -mri->zend;
2585 
2586   xfov = mri->xend - mri->xstart;
2587   yfov = mri->yend - mri->ystart;
2588   zfov = mri->zend - mri->zstart;
2589 
2590   mri->fov =
2591     (xfov > yfov ? (xfov > zfov ? xfov : zfov) : (yfov > zfov ? yfov : zfov));
2592 
2593   strcpy(mri->fname, fname);
2594 
2595   T = MRIxfmCRS2XYZ(mri,0);
2596   printf("Input Coordinate Transform (CRS2XYZ)-------\n");
2597   MatrixPrint(stdout,T);
2598   MatrixFree(&T);
2599   pVox2WorldGen = get_voxel_to_world_transform(vol);
2600   pVox2WorldLin = get_linear_transform_ptr(pVox2WorldGen);
2601   if ((Gdiag & DIAG_SHOW) && DIAG_VERBOSE_ON)
2602     {
2603       printf("MINC Linear Transform ----------------------\n");
2604       for(i=0;i<4;i++){
2605         for(j=0;j<4;j++) printf("%7.4f ",pVox2WorldLin->m[j][i]);
2606         printf("\n");
2607       }
2608       printf("-------------------------------------------\n");
2609     }
2610 
2611   /* ----- copy the data from the file to the mri structure ----- */
2612   if(read_volume){
2613 
2614     while(input_more_of_volume(vol, &input_info, &f));
2615 
2616     for(i = 0;i < mri->width;i++) {
2617       for(j = 0;j < mri->height;j++) {
2618         for(k = 0;k < mri->depth;k++) {
2619           for(t = 0;t < mri->nframes;t++) {
2620             val = get_volume_voxel_value(vol, i, j, k, t, 0);
2621             switch(mri->type){
2622             case MRI_UCHAR: MRIseq_vox(mri,i,j,k,t) = (unsigned char)val;break;
2623             case MRI_SHORT: MRISseq_vox(mri,i,j,k,t) = (short)val;break;
2624             case MRI_LONG:  MRILseq_vox(mri,i,j,k,t) = (long)val;break;
2625             case MRI_FLOAT: MRIFseq_vox(mri,i,j,k,t) = (float)val;break;
2626             }
2627           }
2628         }
2629       }
2630     }
2631   }
2632 
2633   delete_volume_input(&input_info);
2634   delete_volume(vol);
2635 
2636   return(mri);
2637 
2638 } /* end mincRead2() */
2639 /*-----------------------------------------------------------*/
2640 static int GetMINCInfo(MRI *mri,
2641                        char *dim_names[4],
2642                        int   dim_sizes[4],
2643                        Real separations[4],
2644                        Real dircos[3][3],
2645                        Real VolCenterVox[3],
2646                        Real VolCenterWorld[3])
2647 {
2648   int xspacehit, yspacehit, zspacehit;
2649   float col_dc_x, col_dc_y, col_dc_z;
2650   float row_dc_x, row_dc_y, row_dc_z;
2651   float slc_dc_x, slc_dc_y, slc_dc_z;
2652   Real col_dc_sign, row_dc_sign, slc_dc_sign;
2653   int err,i,j;
2654 
2655   col_dc_x = fabs(mri->x_r);
2656   col_dc_y = fabs(mri->x_a);
2657   col_dc_z = fabs(mri->x_s);
2658   col_dc_sign = 1;
2659 
2660   row_dc_x = fabs(mri->y_r);
2661   row_dc_y = fabs(mri->y_a);
2662   row_dc_z = fabs(mri->y_s);
2663   row_dc_sign = 1;
2664 
2665   slc_dc_x = fabs(mri->z_r);
2666   slc_dc_y = fabs(mri->z_a);
2667   slc_dc_z = fabs(mri->z_s);
2668   slc_dc_sign = 1;
2669 
2670   xspacehit = 0;
2671   yspacehit = 0;
2672   zspacehit = 0;
2673 
2674   /* Name the Column Axis */
2675   if(col_dc_x >= row_dc_x && col_dc_x >= slc_dc_x){
2676     dim_names[0] = MIxspace;
2677     VolCenterVox[0] = (mri->width-1)/2.0;
2678     if(mri->x_r < 0) col_dc_sign = -1;
2679     xspacehit = 1;
2680   }
2681   else if(col_dc_y >= row_dc_y && col_dc_y >= slc_dc_y){
2682     dim_names[0] = MIyspace;
2683     VolCenterVox[0] = (mri->height-1)/2.0;
2684     if(mri->x_a < 0) col_dc_sign = -1;
2685     yspacehit = 1;
2686   }
2687   else if(col_dc_z >= row_dc_z && col_dc_z >= slc_dc_z){
2688     dim_names[0] = MIzspace;
2689     VolCenterVox[0] = (mri->depth-1)/2.0;
2690     if(mri->x_s < 0) col_dc_sign = -1;
2691     zspacehit = 1;
2692   }
2693 
2694   /* Name the Row Axis */
2695   if(!xspacehit && row_dc_x >= slc_dc_x){
2696     dim_names[1] = MIxspace;
2697     VolCenterVox[1] = (mri->width-1)/2.0;
2698     if(mri->y_r < 0) row_dc_sign = -1;
2699     xspacehit = 1;
2700   }
2701   else if(!yspacehit && row_dc_y >= slc_dc_y){
2702     dim_names[1] = MIyspace;
2703     VolCenterVox[1] = (mri->height-1)/2.0;
2704     if(mri->y_a < 0) row_dc_sign = -1;
2705     yspacehit = 1;
2706   }
2707   else if(!zspacehit && row_dc_z >= slc_dc_z){
2708     dim_names[1] = MIzspace;
2709     VolCenterVox[1] = (mri->depth-1)/2.0;
2710     if(mri->y_s < 0) row_dc_sign = -1;
2711     zspacehit = 1;
2712   }
2713 
2714   /* Name the Slice Axis */
2715   if(!xspacehit){
2716     dim_names[2] = MIxspace;
2717     VolCenterVox[2] = (mri->width-1)/2.0;
2718     if(mri->z_r < 0) slc_dc_sign = -1;
2719     xspacehit = 1;
2720   }
2721   else if(!yspacehit){
2722     dim_names[2] = MIyspace;
2723     VolCenterVox[2] = (mri->height-1)/2.0;
2724     if(mri->z_a < 0) slc_dc_sign = -1;
2725     yspacehit = 1;
2726   }
2727   if(!zspacehit){
2728     dim_names[2] = MIzspace;
2729     VolCenterVox[2] = (mri->depth-1)/2.0;
2730     if(mri->z_s < 0) slc_dc_sign = -1;
2731     zspacehit = 1;
2732   }
2733 
2734   /* Check for errors in the Axis Naming*/
2735   err = 0;
2736   if(!xspacehit){
2737     printf("ERROR: could not assign xspace\n");
2738     err = 1;
2739   }
2740   if(!yspacehit){
2741     printf("ERROR: could not assign yspace\n");
2742     err = 1;
2743   }
2744   if(!zspacehit){
2745     printf("ERROR: could not assign zspace\n");
2746     err = 1;
2747   }
2748   if(err) return(1);
2749 
2750   /* Name the Frame Axis */
2751   dim_names[3] = MItime;
2752 
2753   /* Set world center */
2754   VolCenterWorld[0] = mri->c_r;
2755   VolCenterWorld[1] = mri->c_a;
2756   VolCenterWorld[2] = mri->c_s;
2757 
2758   /* Set dimension lengths */
2759   dim_sizes[0] = mri->width;
2760   dim_sizes[1] = mri->height;
2761   dim_sizes[2] = mri->depth;
2762   dim_sizes[3] = mri->nframes;
2763 
2764   /* Set separations */
2765   separations[0] = col_dc_sign * mri->xsize;
2766   separations[1] = row_dc_sign * mri->ysize;
2767   separations[2] = slc_dc_sign * mri->zsize;
2768   separations[3] = mri->tr;
2769 
2770   /* Set direction Cosines */
2771   dircos[0][0] = col_dc_sign * mri->x_r;
2772   dircos[0][1] = col_dc_sign * mri->x_a;
2773   dircos[0][2] = col_dc_sign * mri->x_s;
2774 
2775   dircos[1][0] = row_dc_sign * mri->y_r;
2776   dircos[1][1] = row_dc_sign * mri->y_a;
2777   dircos[1][2] = row_dc_sign * mri->y_s;
2778 
2779   dircos[2][0] = slc_dc_sign * mri->z_r;
2780   dircos[2][1] = slc_dc_sign * mri->z_a;
2781   dircos[2][2] = slc_dc_sign * mri->z_s;
2782 
2783   /* This is a hack for the case where the dircos are the default.
2784      The MINC routines will not save the direction cosines as
2785      NetCDF attriubtes if they correspond to the default. */
2786   for(i=0;i<3;i++)
2787     for(j=0;j<3;j++)
2788       if(fabs(dircos[i][j] < .00000000001)) dircos[i][j] = .0000000000000001;
2789 
2790   return(0);
2791 }
2792 
2793 /*-----------------------------------------------------------*/
2794 static int mincWrite2(MRI *mri, char *fname)
2795 {
2796   Volume minc_volume;
2797   nc_type nc_data_type = NC_BYTE;
2798   int ndim,i,j;
2799   Real min, max;
2800   float fmin, fmax;
2801   char *dim_names[4];
2802   int   dim_sizes[4];
2803   Real separations[4];
2804   Real dircos[3][3];
2805   Real VolCenterVox[3];
2806   Real VolCenterWorld[3];
2807   int signed_flag = 0;
2808   int r,c,s,f;
2809   Real VoxVal = 0.0;
2810   int return_value;
2811   VIO_Status status;
2812   MATRIX *T;
2813   Transform *pVox2WorldLin;
2814   General_transform *pVox2WorldGen;
2815 
2816   /* Get the min and max for the volume */
2817   if((return_value = MRIlimits(mri, &fmin, &fmax)) != NO_ERROR)
2818     return(return_value);
2819   min = (Real)fmin;
2820   max = (Real)fmax;
2821 
2822   /* Translate mri type to NetCDF type */
2823   switch(mri->type){
2824   case MRI_UCHAR: nc_data_type = NC_BYTE;  signed_flag = 0; break;
2825   case MRI_SHORT: nc_data_type = NC_SHORT; signed_flag = 1; break;
2826   case MRI_INT:   nc_data_type = NC_LONG;  signed_flag = 1; break;
2827   case MRI_LONG:  nc_data_type = NC_LONG;  signed_flag = 1; break;
2828   case MRI_FLOAT: nc_data_type = NC_FLOAT; signed_flag = 1; break;
2829   }
2830 
2831   /* Assign default direction cosines, if needed */
2832   if(mri->ras_good_flag == 0){
2833     setDirectionCosine(mri, MRI_CORONAL);
2834   }
2835 
2836   GetMINCInfo(mri, dim_names, dim_sizes, separations, dircos,
2837               VolCenterVox,VolCenterWorld);
2838 
2839   if(mri->nframes > 1) ndim = 4;
2840   else                 ndim = 3;
2841 
2842   minc_volume = create_volume(ndim, dim_names, nc_data_type,
2843                               signed_flag, min, max);
2844   set_volume_sizes(minc_volume, dim_sizes);
2845   alloc_volume_data(minc_volume);
2846 
2847   for(i=0;i<3;i++){
2848     printf("%d %s %4d %7.3f  %7.3f %7.3f %7.3f \n",
2849            i,dim_names[i],dim_sizes[i],separations[i],
2850            dircos[i][0],dircos[i][1],dircos[i][2]);
2851     set_volume_direction_cosine(minc_volume, i, dircos[i]);
2852   }
2853   printf("Center Voxel: %7.3f %7.3f %7.3f\n",
2854          VolCenterVox[0],VolCenterVox[1],VolCenterVox[2]);
2855   printf("Center World: %7.3f %7.3f %7.3f\n",
2856          VolCenterWorld[0],VolCenterWorld[1],VolCenterWorld[2]);
2857 
2858   set_volume_separations(minc_volume, separations);
2859   set_volume_translation(minc_volume, VolCenterVox, VolCenterWorld);
2860 
2861   T = MRIxfmCRS2XYZ(mri,0);
2862   printf("MRI Transform -----------------------------\n");
2863   MatrixPrint(stdout,T);
2864   pVox2WorldGen = get_voxel_to_world_transform(minc_volume);
2865   pVox2WorldLin = get_linear_transform_ptr(pVox2WorldGen);
2866   if ((Gdiag & DIAG_SHOW) && DIAG_VERBOSE_ON)
2867     {
2868       printf("MINC Linear Transform ----------------------\n");
2869       for(i=0;i<4;i++){
2870         for(j=0;j<4;j++) printf("%7.4f ",pVox2WorldLin->m[j][i]);
2871         printf("\n");
2872       }
2873       printf("--------------------------------------------\n");
2874     }
2875   MatrixFree(&T);
2876 
2877   printf("Setting Volume Values\n");
2878   for(f = 0; f < mri->nframes; f++) {     /* frames */
2879     for(c = 0; c < mri->width;   c++) {     /* columns */
2880       for(r = 0; r < mri->height;  r++) {     /* rows */
2881         for(s = 0; s < mri->depth;   s++) {     /* slices */
2882 
2883           switch(mri->type){
2884           case MRI_UCHAR: VoxVal = (Real)MRIseq_vox(mri,  c, r, s, f);break;
2885           case MRI_SHORT: VoxVal = (Real)MRISseq_vox(mri, c, r, s, f);break;
2886           case MRI_INT:   VoxVal = (Real)MRIIseq_vox(mri, c, r, s, f);break;
2887           case MRI_LONG:  VoxVal = (Real)MRILseq_vox(mri, c, r, s, f);break;
2888           case MRI_FLOAT: VoxVal = (Real)MRIFseq_vox(mri, c, r, s, f);break;
2889           }
2890           set_volume_voxel_value(minc_volume, c, r, s, f, 0, VoxVal);
2891         }
2892       }
2893     }
2894   }
2895 
2896   printf("Writing Volume\n");
2897   status = output_volume((STRING)fname, nc_data_type, signed_flag, min, max,
2898                          minc_volume, (STRING)"", NULL);
2899   printf("Cleaning Up\n");
2900   delete_volume(minc_volume);
2901 
2902   if(status) {
2903     printf("ERROR: mincWrite: output_volume exited with %d\n",status);
2904     return(1);
2905   }
2906 
2907   printf("mincWrite2: done\n");
2908   return(NO_ERROR);
2909 }
2910 
2911 
2912 /*-------------------------------------------------------
2913   NormalizeVector() - in-place vector normalization
2914   -------------------------------------------------------*/
2915 static int NormalizeVector(float *v, int n)
2916 {
2917   float sum2;
2918   int i;
2919   sum2 = 0;
2920   for(i=0;i<n;i++) sum2 += v[i];
2921   sum2 = sqrt(sum2);
2922   for(i=0;i<n;i++) v[i] /= sum2;
2923   return(0);
2924 }
2925 #endif
2926 /*----------------------------------------------------------*/
2927 /* time course clean */
2928 static int mincWrite(MRI *mri, char *fname)
2929 {
2930 
2931   Volume minc_volume;
2932   STRING dimension_names[4] = { "xspace", "yspace", "zspace", "time" };
2933   nc_type nc_data_type;
2934   Real min, max;
2935   float fmin, fmax;
2936   int dimension_sizes[4];
2937   Real separations[4];
2938   Real dir_cos[4];
2939   int return_value;
2940   Real voxel[4], world[4];
2941   int signed_flag;
2942   int di_x, di_y, di_z;
2943   int vi[4];
2944   /*   int r, a, s; */
2945   /*   float r_max; */
2946   VIO_Status status;
2947 
2948   /* di gives the bogus minc index
2949      di[0] is width, 1 is height, 2 is depth, 3 is time if
2950      there is a time dimension of length > 1
2951      minc wants these to be ras */
2952 
2953   /* here: minc volume index 0 is r, 1 is a, 2 is s */
2954   /* mri is lia *//* (not true for some volumes *)*/
2955 
2956   /* ----- get the orientation of the volume ----- */
2957   if(mri->ras_good_flag == 0)
2958     {
2959       setDirectionCosine(mri, MRI_CORONAL);
2960     }
2961 
2962   /* we don't muck around axes anymore */
2963   di_x = 0;
2964   di_y = 1;
2965   di_z = 2;
2966 
2967 #if 0
2968   /*  The following remapping is only valid for COR files */
2969   /*  In order to handle arbitrary volumes, we don't muck around */
2970   /*  the axes anymore  ... tosa */
2971 
2972   /* orig->minc map ***********************************/
2973   /* r axis is mapped to (x_r, y_r, z_r) voxel coords */
2974   /* thus find the biggest value among x_r, y_r, z_r  */
2975   /* that one corresponds to the r-axis               */
2976   r = 0;
2977   r_max = fabs(mri->x_r);
2978   if(fabs(mri->y_r) > r_max)
2979     {
2980       r_max = fabs(mri->y_r);
2981       r = 1;
2982     }
2983   if(fabs(mri->z_r) > r_max)
2984     r = 2;
2985 
2986   /* a axis is mapped to (x_a, y_a, z_a) voxel coords */
2987   if(r == 0)
2988     a = (fabs(mri->y_a) > fabs(mri->z_a) ? 1 : 2);
2989   else if(r == 1)
2990     a = (fabs(mri->x_a) > fabs(mri->z_a) ? 0 : 2);
2991   else
2992     a = (fabs(mri->x_a) > fabs(mri->y_a) ? 0 : 1);
2993 
2994   /* s axis is mapped to (x_s, y_s, z_s) voxel coords */
2995   /* use the rest to figure                           */
2996   s = 3 - r - a;
2997 
2998   /* ----- set the appropriate minc axes to this orientation ----- */
2999   /* r gives the mri structure axis of the lr coordinate */
3000   /* lr = minc xspace = 0 */
3001   /* a ..... of the pa coordinate *//* pa = minc yspace = 1 */
3002   /* s ..... of the is coordinate *//* is = minc zspace = 2 */
3003 
3004   /* di of this axis must be set to 2 */
3005   /* ... and so on */
3006 
3007   /* minc->orig map **************************************/
3008   /* you don't need the routine above but do a similar thing */
3009   /* to get exactly the same, i.e.                           */
3010   /* x-axis corresponds to (x_r, x_a, x_s) minc coords */
3011   /* y-axis                (y_r, y_a, y_s) minc coords */
3012   /* z-axis                (z_r, z_a, z_s) minc coords */
3013   /* thus we are doing too much work                   */
3014 
3015   if(r == 0)
3016     {
3017       if(a == 1)
3018         {
3019           di_x = 0;
3020           di_y = 1;
3021           di_z = 2;
3022         }
3023       else
3024         {
3025           di_x = 0;
3026           di_y = 2;
3027           di_z = 1;
3028         }
3029     }
3030   else if(r == 1)
3031     {
3032       if(a == 0)
3033         {
3034           di_x = 1;
3035           di_y = 0;
3036           di_z = 2;
3037         }
3038       else
3039         {
3040           di_x = 2;
3041           di_y = 0;
3042           di_z = 1;
3043         }
3044     }
3045   else
3046     {
3047       if(a == 0)
3048         {
3049           di_x = 1;
3050           di_y = 2;
3051           di_z = 0;
3052         }
3053       else
3054         {
3055           di_x = 2;
3056           di_y = 1;
3057           di_z = 0;
3058         }
3059     }
3060 #endif
3061 
3062   /* ----- set the data type ----- */
3063   if(mri->type == MRI_UCHAR)
3064     {
3065       nc_data_type = NC_BYTE;
3066       signed_flag = 0;
3067     }
3068   else if(mri->type == MRI_SHORT)
3069     {
3070       nc_data_type = NC_SHORT;
3071       signed_flag = 1;
3072     }
3073   else if(mri->type == MRI_INT)
3074     {
3075       nc_data_type = NC_LONG;
3076       signed_flag = 1;
3077     }
3078   else if(mri->type == MRI_LONG)
3079     {
3080       nc_data_type = NC_LONG;
3081       signed_flag = 1;
3082     }
3083   else if(mri->type == MRI_FLOAT)
3084     {
3085       nc_data_type = NC_FLOAT;
3086       signed_flag = 1;
3087     }
3088   else
3089     {
3090       errno = 0;
3091       ErrorReturn
3092         (ERROR_BADPARM,
3093          (ERROR_BADPARM,
3094           "mincWrite(): bad data type (%d) in mri structure",
3095           mri->type));
3096     }
3097 
3098   if((return_value = MRIlimits(mri, &fmin, &fmax)) != NO_ERROR)
3099     return(return_value);
3100 
3101   min = (Real)fmin;
3102   max = (Real)fmax;
3103 
3104   if(mri->nframes == 1)
3105     minc_volume = create_volume
3106       (3, dimension_names, nc_data_type, signed_flag, min, max);
3107   else
3108     minc_volume = create_volume
3109       (4, dimension_names, nc_data_type, signed_flag, min, max);
3110 
3111   /* di_(x,y,z) is the map from minc to orig */
3112   /* minc dimension size is that of di_x, etc. */
3113   dimension_sizes[di_x] = mri->width;
3114   dimension_sizes[di_y] = mri->height;
3115   dimension_sizes[di_z] = mri->depth;
3116   dimension_sizes[3] = mri->nframes;
3117 
3118   set_volume_sizes(minc_volume, dimension_sizes);
3119 
3120   alloc_volume_data(minc_volume);
3121 
3122   separations[di_x] = (Real)(mri->xsize);
3123   separations[di_y] = (Real)(mri->ysize);
3124   separations[di_z] = (Real)(mri->zsize);
3125   separations[3] = 1.0; // appears to do nothing
3126   set_volume_separations(minc_volume, separations);
3127   /* has side effect to change transform and thus must be set first */
3128 
3129   dir_cos[0] = (Real)mri->x_r;
3130   dir_cos[1] = (Real)mri->x_a;
3131   dir_cos[2] = (Real)mri->x_s;
3132   set_volume_direction_cosine(minc_volume, di_x, dir_cos);
3133 
3134   dir_cos[0] = (Real)mri->y_r;
3135   dir_cos[1] = (Real)mri->y_a;
3136   dir_cos[2] = (Real)mri->y_s;
3137   set_volume_direction_cosine(minc_volume, di_y, dir_cos);
3138 
3139   dir_cos[0] = (Real)mri->z_r;
3140   dir_cos[1] = (Real)mri->z_a;
3141   dir_cos[2] = (Real)mri->z_s;
3142   set_volume_direction_cosine(minc_volume, di_z, dir_cos);
3143 
3144   voxel[di_x] = mri->width / 2.0; // promoted to double
3145   voxel[di_y] = mri->height/ 2.0;
3146   voxel[di_z] = mri->depth / 2.0;
3147   voxel[3] = 0.0;
3148   world[0] = (Real)(mri->c_r);
3149   world[1] = (Real)(mri->c_a);
3150   world[2] = (Real)(mri->c_s);
3151   world[3] = 0.0;
3152   set_volume_translation(minc_volume, voxel, world);
3153 
3154   /* get the position from (vi[di_x], vi[di_y], vi[di_z]) orig position     */
3155   /*      put the value to (vi[0], vi[1], vi[2]) minc volume                */
3156   /* this will keep the orientation of axes the same as the original        */
3157 
3158   /* vi[n] gives the index of the variable along minc axis x */
3159   /* vi[di_x] gives the index of the variable
3160      along minc axis di_x, or along mri axis x */
3161   for(vi[3] = 0;vi[3] < mri->nframes;vi[3]++) {           /* frames */
3162     for(vi[di_x] = 0;vi[di_x] < mri->width;vi[di_x]++) {   /* columns */
3163       for(vi[di_y] = 0;vi[di_y] < mri->height;vi[di_y]++) { /* rows */
3164         for(vi[di_z] = 0;vi[di_z] < mri->depth;vi[di_z]++) { /* slices */
3165 
3166           if(mri->type == MRI_UCHAR)
3167             set_volume_voxel_value
3168               (minc_volume, vi[0], vi[1], vi[2], vi[3], 0,
3169                (Real)MRIseq_vox(mri, vi[di_x], vi[di_y], vi[di_z], vi[3]));
3170           if(mri->type == MRI_SHORT)
3171             set_volume_voxel_value
3172               (minc_volume, vi[0], vi[1], vi[2], vi[3], 0,
3173                (Real)MRISseq_vox(mri, vi[di_x], vi[di_y], vi[di_z], vi[3]));
3174           if(mri->type == MRI_INT)
3175             set_volume_voxel_value
3176               (minc_volume, vi[0], vi[1], vi[2], vi[3], 0,
3177                (Real)MRIIseq_vox(mri, vi[di_x], vi[di_y], vi[di_z], vi[3]));
3178           if(mri->type == MRI_LONG)
3179             set_volume_voxel_value
3180               (minc_volume, vi[0], vi[1], vi[2], vi[3], 0,
3181                (Real)MRILseq_vox(mri, vi[di_x], vi[di_y], vi[di_z], vi[3]));
3182           if(mri->type == MRI_FLOAT)
3183             set_volume_voxel_value
3184               (minc_volume, vi[0], vi[1], vi[2], vi[3], 0,
3185                (Real)MRIFseq_vox(mri, vi[di_x], vi[di_y], vi[di_z], vi[3]));
3186         }
3187       }
3188     }
3189   }
3190 
3191   status = output_volume((STRING)fname, nc_data_type, signed_flag, min, max,
3192                          minc_volume, (STRING)"", NULL);
3193   delete_volume(minc_volume);
3194 
3195   if(status) {
3196     printf("ERROR: mincWrite: output_volume exited with %d\n",status);
3197     return(1);
3198   }
3199 
3200   return(NO_ERROR);
3201 
3202 } /* end mincWrite() */
3203 
3204 
3205 /*----------------------------------------------------------------
3206   bvolumeWrite() - replaces bshortWrite and bfloatWrite.
3207   Bug: fname_passed must the the stem, not the full file name.
3208   -----------------------------------------------------------------*/
3209 static int bvolumeWrite(MRI *vol, char *fname_passed, int type)
3210 {
3211 
3212   int i, j, t;
3213   char fname[STRLEN];
3214   short *bufshort;
3215   float *buffloat;
3216   FILE *fp;
3217   int result;
3218   MRI *subject_info = NULL;
3219   char subject_volume_dir[STRLEN];
3220   char *subjects_dir;
3221   char *sn;
3222   char analyse_fname[STRLEN], register_fname[STRLEN];
3223   char output_dir[STRLEN];
3224   char *c;
3225   int od_length;
3226   char t1_path[STRLEN];
3227   MATRIX *cf, *bf, *ibf, *af, *iaf, *as, *bs, *cs, *ics, *r;
3228   MATRIX *r1, *r2, *r3, *r4;
3229   float det;
3230   int bad_flag;
3231   int l;
3232   char stem[STRLEN];
3233   char *c1, *c2, *c3;
3234   struct stat stat_buf;
3235   char subject_dir[STRLEN];
3236   int dealloc, nslices, nframes;
3237   MRI *mri;
3238   float min,max;
3239   int swap_bytes_flag, size, bufsize;
3240   char *ext;
3241   void *buf;
3242 
3243   /* check the type and set the extension and size*/
3244   switch(type) {
3245   case MRI_SHORT: ext = "bshort"; size = sizeof(short); break;
3246   case MRI_FLOAT: ext = "bfloat"; size = sizeof(float); break;
3247   default:
3248     fprintf
3249       (stderr,"ERROR: bvolumeWrite: type (%d) is not short or float\n", type);
3250     return(1);
3251   }
3252 
3253   if(vol->type != type){
3254     if (DIAG_VERBOSE_ON)
3255       printf("INFO: bvolumeWrite: changing type\n");
3256     nslices = vol->depth;
3257     nframes = vol->nframes;
3258     vol->depth = nslices*nframes;
3259     vol->nframes = 1;
3260     MRIlimits(vol,&min,&max);
3261     if (DIAG_VERBOSE_ON)
3262       printf("INFO: bvolumeWrite: range %g %g\n",min,max);
3263     mri = MRIchangeType(vol,type,min,max,1);
3264     if(mri == NULL) {
3265       fprintf(stderr,"ERROR: bvolumeWrite: MRIchangeType\n");
3266       return(1);
3267     }
3268     vol->depth = nslices;
3269     vol->nframes = nframes;
3270     mri->depth = nslices;
3271     mri->nframes = nframes;
3272     dealloc = 1;
3273   }
3274   else{
3275     mri = vol;
3276     dealloc = 0;
3277   }
3278 
3279   /* ----- get the stem from the passed file name ----- */
3280   /*
3281     four options:
3282     1. stem_xxx.bshort
3283     2. stem.bshort
3284     3. stem_xxx
3285     4. stem
3286     other possibles:
3287     stem_.bshort
3288   */
3289   l = strlen(fname_passed);
3290   c1 = fname_passed + l - 11;
3291   c2 = fname_passed + l - 7;
3292   c3 = fname_passed + l - 4;
3293   strcpy(stem, fname_passed);
3294   if(c1 > fname_passed)
3295     {
3296       if( (*c1 == '_' && strcmp(c1+4, ".bshort") == 0) ||
3297           (*c1 == '_' && strcmp(c1+4, ".bfloat") == 0) )
3298         stem[(int)(c1-fname_passed)] = '\0';
3299     }
3300   if(c2 > fname_passed)
3301     {
3302       if( (*c2 == '_' && strcmp(c2+4, ".bshort") == 0) ||
3303           (*c2 == '_' && strcmp(c2+4, ".bfloat") == 0) )
3304         stem[(int)(c2-fname_passed)] = '\0';
3305 
3306     }
3307   if(c3 > fname_passed)
3308     {
3309       if(*c3 == '_')
3310         stem[(int)(c3-fname_passed)] = '\0';
3311     }
3312   printf("INFO: bvolumeWrite: stem = %s\n",stem);
3313 
3314   c = strrchr(stem, '/');
3315   if(c == NULL)
3316     output_dir[0] = '\0';
3317   else
3318     {
3319       od_length = (int)(c - stem);
3320       strncpy(output_dir, stem, od_length);
3321       /* -- leaving the trailing '/' on a directory is not my
3322          usual convention, but here it's a load easier if there's
3323          no directory in stem... -ch -- */
3324       output_dir[od_length] = '/';
3325       output_dir[od_length+1] = '\0';
3326     }
3327 
3328   sprintf(analyse_fname, "%s%s", output_dir, "analyse.dat");
3329   sprintf(register_fname, "%s%s", output_dir, "register.dat");
3330 
3331   bufsize  = mri->width * size;
3332   bufshort = (short *)malloc(bufsize);
3333   buffloat = (float *)malloc(bufsize);
3334 
3335   buf = NULL; /* shuts up compiler */
3336   if(type == MRI_SHORT)  buf = bufshort;
3337   else                   buf = buffloat;
3338 
3339   swap_bytes_flag = 0;
3340 #if (BYTE_ORDER==LITTLE_ENDIAN)
3341   swap_bytes_flag = 1;
3342 #endif
3343 
3344   //printf("--------------------------------\n");
3345   //MRIdump(mri,stdout);
3346   //MRIdumpBuffer(mri,stdout);
3347   //printf("--------------------------------\n");
3348 
3349   for(i = 0;i < mri->depth;i++)
3350     {
3351 
3352       /* ----- write the header file ----- */
3353       sprintf(fname, "%s_%03d.hdr", stem, i);
3354       if((fp = fopen(fname, "w")) == NULL)
3355         {
3356           if(dealloc) MRIfree(&mri);
3357           free(bufshort);
3358           free(buffloat);
3359           errno = 0;
3360           ErrorReturn
3361             (ERROR_BADFILE, (ERROR_BADFILE,
3362                              "bvolumeWrite(): can't open file %s", fname));
3363         }
3364       fprintf(fp, "%d %d %d %d\n", mri->height, mri->width, mri->nframes, 0);
3365       fclose(fp);
3366 
3367       /* ----- write the data file ----- */
3368       sprintf(fname, "%s_%03d.%s", stem, i, ext);
3369       if((fp = fopen(fname, "w")) == NULL)
3370         {
3371           if(dealloc) MRIfree(&mri);
3372           free(bufshort);
3373           free(buffloat);
3374           errno = 0;
3375           ErrorReturn
3376             (ERROR_BADFILE, (ERROR_BADFILE,
3377                              "bvolumeWrite(): can't open file %s", fname));
3378         }
3379 
3380       for(t = 0;t < mri->nframes;t++) {
3381         for(j = 0;j < mri->height;j++) {
3382           memcpy(buf,mri->slices[t*mri->depth + i][j], bufsize);
3383 
3384           if(swap_bytes_flag){
3385             if(type == MRI_SHORT) byteswapbufshort((void*)buf, bufsize);
3386             else                  byteswapbuffloat((void*)buf, bufsize);
3387           }
3388           fwrite(buf, size, mri->width, fp);
3389         }
3390       }
3391 
3392       fclose(fp);
3393     }
3394 
3395   free(bufshort);
3396   free(buffloat);
3397 
3398   sn = subject_name;
3399   if(mri->subject_name[0] != '\0')
3400     sn = mri->subject_name;
3401 
3402   if(sn != NULL)
3403     {
3404       if((subjects_dir = getenv("SUBJECTS_DIR")) == NULL)
3405         {
3406           errno = 0;
3407           ErrorPrintf
3408             (ERROR_BADPARM,
3409              "bvolumeWrite(): environment variable SUBJECTS_DIR unset");
3410           if(dealloc) MRIfree(&mri);
3411         }
3412       else
3413         {
3414 
3415           sprintf(subject_dir, "%s/%s", subjects_dir, sn);
3416           if(stat(subject_dir, &stat_buf) < 0)
3417             {
3418               fprintf
3419                 (stderr,
3420                  "can't stat %s; writing to bhdr instead\n", subject_dir);
3421             }
3422           else
3423             {
3424               if(!S_ISDIR(stat_buf.st_mode))
3425                 {
3426                   fprintf
3427                     (stderr,
3428                      "%s is not a directory; writing to bhdr instead\n",
3429                      subject_dir);
3430                 }
3431               else
3432                 {
3433                   sprintf(subject_volume_dir, "%s/mri/T1", subject_dir);
3434                   subject_info = MRIreadInfo(subject_volume_dir);
3435                   if(subject_info == NULL)
3436                     {
3437                       sprintf(subject_volume_dir, "%s/mri/orig", subject_dir);
3438                       subject_info = MRIreadInfo(subject_volume_dir);
3439                       if(subject_info == NULL)
3440                         fprintf(stderr,
3441                                 "can't read the subject's orig or T1 volumes; "
3442                                 "writing to bhdr instead\n");
3443                     }
3444                 }
3445             }
3446 
3447         }
3448 
3449     }
3450 
3451   if(subject_info != NULL)
3452     {
3453       if(subject_info->ras_good_flag == 0)
3454         {
3455           setDirectionCosine(subject_info, MRI_CORONAL);
3456         }
3457     }
3458 
3459   cf = bf = ibf = af = iaf = as = bs = cs = ics = r = NULL;
3460   r1 = r2 = r3 = r4 = NULL;
3461 
3462   /* ----- write the register.dat and analyse.dat  or bhdr files ----- */
3463   if(subject_info != NULL)
3464     {
3465 
3466       bad_flag = FALSE;
3467 
3468       if((as = MatrixAlloc(4, 4, MATRIX_REAL)) == NULL)
3469         {
3470           errno = 0;
3471           ErrorPrintf(ERROR_BADPARM, "bvolumeWrite(): error creating matrix");
3472           bad_flag = TRUE;
3473         }
3474       stuff_four_by_four
3475         (as, subject_info->x_r, subject_info->y_r, subject_info->z_r, subject_info->c_r,
3476          subject_info->y_r, subject_info->y_r, subject_info->y_r, subject_info->c_r,
3477          subject_info->z_r, subject_info->z_r, subject_info->z_r, subject_info->c_r,
3478          0.0,               0.0,               0.0,               1.0);
3479 
3480       if((af = MatrixAlloc(4, 4, MATRIX_REAL)) == NULL)
3481         {
3482           errno = 0;
3483           ErrorPrintf(ERROR_BADPARM, "bvolumeWrite(): error creating matrix");
3484           bad_flag = TRUE;
3485         }
3486       stuff_four_by_four(af, mri->x_r, mri->y_r, mri->z_r, mri->c_r,
3487                          mri->y_r, mri->y_r, mri->y_r, mri->c_r,
3488                          mri->z_r, mri->z_r, mri->z_r, mri->c_r,
3489                          0.0,      0.0,      0.0,      1.0);
3490 
3491       if((bs = MatrixAlloc(4, 4, MATRIX_REAL)) == NULL)
3492         {
3493           errno = 0;
3494           ErrorPrintf(ERROR_BADPARM, "bvolumeWrite(): error creating matrix");
3495           bad_flag = TRUE;
3496         }
3497       stuff_four_by_four(bs, 1, 0, 0, (subject_info->width  - 1) / 2.0,
3498                          0, 1, 0, (subject_info->height - 1) / 2.0,
3499                          0, 0, 1, (subject_info->depth  - 1) / 2.0,
3500                          0, 0, 0,                              1.0);
3501 
3502       if((bf = MatrixAlloc(4, 4, MATRIX_REAL)) == NULL)
3503         {
3504           errno = 0;
3505           ErrorPrintf(ERROR_BADPARM, "bvolumeWrite(): error creating matrix");
3506           bad_flag = TRUE;
3507         }
3508       stuff_four_by_four(bf, 1, 0, 0, (mri->width  - 1) / 2.0,
3509                          0, 1, 0, (mri->height - 1) / 2.0,
3510                          0, 0, 1, (mri->depth  - 1) / 2.0,
3511                          0, 0, 0,                     1.0);
3512 
3513       if((cs = MatrixAlloc(4, 4, MATRIX_REAL)) == NULL)
3514         {
3515           errno = 0;
3516           ErrorPrintf(ERROR_BADPARM, "bvolumeWrite(): error creating matrix");
3517           bad_flag = TRUE;
3518         }
3519       stuff_four_by_four
3520         (cs,
3521          -subject_info->xsize, 0, 0,(subject_info->width  * mri->xsize) / 2.0,\
3522          0, 0, subject_info->zsize, -(subject_info->depth  * mri->zsize) / 2.0, \
3523          0, -subject_info->ysize, 0,  (subject_info->height * mri->ysize) / 2.0, \
3524          0, 0, 0, 1);
3525 
3526       if((cf = MatrixAlloc(4, 4, MATRIX_REAL)) == NULL)
3527         {
3528           errno = 0;
3529           ErrorPrintf(ERROR_BADPARM, "bvolumeWrite(): error creating matrix");
3530           bad_flag = TRUE;
3531         }
3532       stuff_four_by_four
3533         (cf,
3534          -mri->xsize, 0,          0,  (mri->width  * mri->xsize) / 2.0,
3535          0,           0, mri->zsize, -(mri->depth  * mri->zsize) / 2.0,
3536          0, -mri->ysize,          0,  (mri->height * mri->ysize) / 2.0,
3537          0,           0,          0,                                 1);
3538 
3539       if(bad_flag)
3540         {
3541           errno = 0;
3542           ErrorPrintf
3543             (ERROR_BADPARM,
3544              "bvolumeWrite(): error creating one "
3545              "or more matrices; aborting register.dat "
3546              "write and writing bhdr instead");
3547           MRIfree(&subject_info);
3548         }
3549 
3550     }
3551 
3552   if(subject_info != NULL)
3553     {
3554 
3555       bad_flag = FALSE;
3556 
3557       if((det = MatrixDeterminant(as)) == 0.0)
3558         {
3559           errno = 0;
3560           ErrorPrintf
3561             (ERROR_BADPARM,
3562              "bvolumeWrite(): bad determinant in "
3563              "matrix (check structural volume)");
3564           bad_flag = TRUE;
3565         }
3566       if((det = MatrixDeterminant(bs)) == 0.0)
3567         {
3568           errno = 0;
3569           ErrorPrintf
3570             (ERROR_BADPARM,
3571              "bvolumeWrite(): bad determinant in "
3572              "matrix (check structural volume)");
3573           bad_flag = TRUE;
3574         }
3575       if((det = MatrixDeterminant(cs)) == 0.0)
3576         {
3577           errno = 0;
3578           ErrorPrintf
3579             (ERROR_BADPARM,
3580              "bvolumeWrite(): bad determinant in "
3581              "matrix (check structural volume)");
3582           bad_flag = TRUE;
3583         }
3584 
3585       if((det = MatrixDeterminant(af)) == 0.0)
3586         {
3587           errno = 0;
3588           ErrorPrintf
3589             (ERROR_BADPARM,
3590              "bvolumeWrite(): bad determinant in "
3591              "matrix (check functional volume)");
3592           bad_flag = TRUE;
3593         }
3594       if((det = MatrixDeterminant(bf)) == 0.0)
3595         {
3596           errno = 0;
3597           ErrorPrintf
3598             (ERROR_BADPARM,
3599              "bvolumeWrite(): bad determinant in "
3600              "matrix (check functional volume)");
3601           bad_flag = TRUE;
3602         }
3603       if((det = MatrixDeterminant(cf)) == 0.0)
3604         {
3605           errno = 0;
3606           ErrorPrintf
3607             (ERROR_BADPARM,
3608              "bvolumeWrite(): bad determinant in "
3609              "matrix (check functional volume)");
3610           bad_flag = TRUE;
3611         }
3612 
3613       if(bad_flag)
3614         {
3615           errno = 0;
3616           ErrorPrintf
3617             (ERROR_BADPARM, "bvolumeWrite(): one or more zero determinants;"
3618              " aborting register.dat write and writing bhdr instead");
3619           MRIfree(&subject_info);
3620         }
3621 
3622     }
3623 
3624   if(subject_info != NULL)
3625     {
3626 
3627       bad_flag = FALSE;
3628 
3629       if((iaf = MatrixInverse(af, NULL)) == NULL)
3630         {
3631           errno = 0;
3632           ErrorPrintf(ERROR_BADPARM, "bvolumeWrite(): error inverting matrix");
3633           bad_flag = TRUE;
3634         }
3635       if((ibf = MatrixInverse(bf, NULL)) == NULL)
3636         {
3637           errno = 0;
3638           ErrorPrintf(ERROR_BADPARM, "bvolumeWrite(): error inverting matrix");
3639           bad_flag = TRUE;
3640         }
3641       if((ics = MatrixInverse(cs, NULL)) == NULL)
3642         {
3643           errno = 0;
3644           ErrorPrintf(ERROR_BADPARM, "bvolumeWrite(): error inverting matrix");
3645           bad_flag = TRUE;
3646         }
3647 
3648       if(bad_flag)
3649         {
3650           errno = 0;
3651           ErrorPrintf
3652             (ERROR_BADPARM, "bvolumeWrite(): one or more zero determinants; "
3653              "aborting register.dat write and writing bhdr instead");
3654           MRIfree(&subject_info);
3655         }
3656     }
3657 
3658   bad_flag = FALSE;
3659 
3660   if(subject_info != NULL)
3661     {
3662 
3663       if((r1 = MatrixMultiply(bs, ics, NULL)) == NULL)
3664         {
3665           bad_flag = TRUE;
3666           MRIfree(&subject_info);
3667         }
3668 
3669     }
3670 
3671   if(subject_info != NULL)
3672     {
3673 
3674       if((r2 = MatrixMultiply(as, r1, NULL)) == NULL)
3675         {
3676           bad_flag = TRUE;
3677           MRIfree(&subject_info);
3678         }
3679 
3680     }
3681 
3682   if(subject_info != NULL)
3683     {
3684 
3685       if((r3 = MatrixMultiply(iaf, r2, NULL)) == NULL)
3686         {
3687           bad_flag = TRUE;
3688           MRIfree(&subject_info);
3689         }
3690 
3691     }
3692 
3693   if(subject_info != NULL)
3694     {
3695 
3696       if((r4 = MatrixMultiply(ibf, r3, NULL)) == NULL)
3697         {
3698           bad_flag = TRUE;
3699           MRIfree(&subject_info);
3700         }
3701 
3702     }
3703 
3704   if(subject_info != NULL)
3705     {
3706 
3707       if((r = MatrixMultiply(cf, r4, NULL)) == NULL)
3708         {
3709           bad_flag = TRUE;
3710           MRIfree(&subject_info);
3711         }
3712 
3713     }
3714 
3715   if(bad_flag)
3716     {
3717       errno = 0;
3718       ErrorPrintf
3719         (ERROR_BADPARM, "bvolumeWrite(): error during matrix multiplications; "
3720          "aborting register.dat write and writing bhdr instead");
3721     }
3722 
3723   if( as != NULL)  MatrixFree( &as);
3724   if( bs != NULL)  MatrixFree( &bs);
3725   if( cs != NULL)  MatrixFree( &cs);
3726   if( af != NULL)  MatrixFree( &af);
3727   if( bf != NULL)  MatrixFree( &bf);
3728   if( cf != NULL)  MatrixFree( &cf);
3729   if(iaf != NULL)  MatrixFree(&iaf);
3730   if(ibf != NULL)  MatrixFree(&ibf);
3731   if(ics != NULL)  MatrixFree(&ics);
3732   if( r1 != NULL)  MatrixFree( &r1);
3733   if( r2 != NULL)  MatrixFree( &r2);
3734   if( r3 != NULL)  MatrixFree( &r3);
3735   if( r4 != NULL)  MatrixFree( &r4);
3736 
3737   if(subject_info != NULL)
3738     {
3739 
3740       if(mri->path_to_t1[0] == '\0')
3741         sprintf(t1_path, ".");
3742       else
3743         strcpy(t1_path, mri->path_to_t1);
3744 
3745       if(FileExists(analyse_fname))
3746         fprintf(stderr, "warning: overwriting file %s\n", analyse_fname);
3747 
3748       if((fp = fopen(analyse_fname, "w")) == NULL)
3749         {
3750           MRIfree(&subject_info);
3751           errno = 0;
3752           ErrorReturn
3753             (ERROR_BADFILE,
3754              (ERROR_BADFILE,
3755               "bvolumeWrite(): couldn't open file %s for writing",
3756               analyse_fname));
3757         }
3758 
3759       fprintf(fp, "%s\n", t1_path);
3760       fprintf(fp, "%s_%%03d.bshort\n", stem);
3761       fprintf(fp, "%d %d\n", mri->depth, mri->nframes);
3762       fprintf(fp, "%d %d\n", mri->width, mri->height);
3763 
3764       fclose(fp);
3765 
3766       if(FileExists(analyse_fname))
3767         fprintf(stderr, "warning: overwriting file %s\n", register_fname);
3768 
3769       if((fp = fopen(register_fname, "w")) == NULL)
3770         {
3771           MRIfree(&subject_info);
3772           errno = 0;
3773           ErrorReturn
3774             (ERROR_BADFILE,
3775              (ERROR_BADFILE,
3776               "bvolumeWrite(): couldn't open file %s for writing",
3777               register_fname));
3778         }
3779 
3780       fprintf(fp, "%s\n", sn);
3781       fprintf(fp, "%g\n", mri->xsize);
3782       fprintf(fp, "%g\n", mri->zsize);
3783       fprintf(fp, "%g\n", 1.0);
3784       fprintf(fp, "%g %g %g %g\n", \
3785               *MATRIX_RELT(r, 1, 1),
3786               *MATRIX_RELT(r, 1, 2),
3787               *MATRIX_RELT(r, 1, 3),
3788               *MATRIX_RELT(r, 1, 4));
3789       fprintf(fp, "%g %g %g %g\n", \
3790               *MATRIX_RELT(r, 2, 1),
3791               *MATRIX_RELT(r, 2, 2),
3792               *MATRIX_RELT(r, 2, 3),
3793               *MATRIX_RELT(r, 2, 4));
3794       fprintf(fp, "%g %g %g %g\n", \
3795               *MATRIX_RELT(r, 3, 1),
3796               *MATRIX_RELT(r, 3, 2),
3797               *MATRIX_RELT(r, 3, 3),
3798               *MATRIX_RELT(r, 3, 4));
3799       fprintf(fp, "%g %g %g %g\n", \
3800               *MATRIX_RELT(r, 4, 1),
3801               *MATRIX_RELT(r, 4, 2),
3802               *MATRIX_RELT(r, 4, 3),
3803               *MATRIX_RELT(r, 4, 4));
3804 
3805       fclose(fp);
3806 
3807       MatrixFree(&r);
3808 
3809     }
3810 
3811   if(subject_info == NULL)
3812     {
3813       sprintf(fname, "%s.bhdr", stem);
3814       if((fp = fopen(fname, "w")) == NULL)
3815         {
3816           if(dealloc) MRIfree(&mri);
3817           errno = 0;
3818           ErrorReturn
3819             (ERROR_BADFILE,
3820              (ERROR_BADFILE, "bvolumeWrite(): can't open file %s", fname));
3821         }
3822 
3823       result = write_bhdr(mri, fp);
3824 
3825       fclose(fp);
3826 
3827       if(result != NO_ERROR)
3828         return(result);
3829 
3830     }
3831   else
3832     MRIfree(&subject_info);
3833 
3834   if(dealloc) MRIfree(&mri);
3835 
3836   return(NO_ERROR);
3837 
3838 } /* end bvolumeWrite() */
3839 
3840 static MRI *get_b_info
3841 (char *fname_passed, int read_volume, char *directory, char *stem, int type)
3842 {
3843 
3844   MRI *mri, *mri2;
3845   FILE *fp;
3846   int nslices=0, nt;
3847   int nx, ny;
3848   int result;
3849   char fname[STRLEN];
3850   char extension[STRLEN];
3851   char bhdr_name[STRLEN];
3852 
3853   if(type == MRI_SHORT)      sprintf(extension, "bshort");
3854   else if(type == MRI_FLOAT) sprintf(extension, "bfloat");
3855   else{
3856     errno = 0;
3857     ErrorReturn(NULL, (ERROR_UNSUPPORTED,
3858                        "internal error: get_b_info() passed type %d", type));
3859   }
3860 
3861   result = decompose_b_fname(fname_passed, directory, stem);
3862   if(result != NO_ERROR) return(NULL);
3863 
3864   if(directory[0] == '\0') sprintf(directory, ".");
3865 
3866 #if 0
3867 
3868   char sn[STRLEN];
3869   char fname_descrip[STRLEN];
3870   float fov_x, fov_y, fov_z;
3871   MATRIX *m;
3872   int res;
3873   char register_fname[STRLEN], analyse_fname[STRLEN];
3874   float ipr, st, intensity;
3875   float m11, m12, m13, m14;
3876   float m21, m22, m23, m24;
3877   float m31, m32, m33, m34;
3878   float m41, m42, m43, m44;
3879   char t1_path[STRLEN];
3880 
3881   /* ----- try register.dat and analyse.dat, then bhdr, then defaults ----- */
3882   sprintf(register_fname, "%s/register.dat", directory);
3883   sprintf(analyse_fname, "%s/analyse.dat", directory);
3884 
3885   if((fp = fopen(register_fname, "r")) != NULL)
3886     {
3887 
3888       fscanf(fp, "%s", sn);
3889       fscanf(fp, "%f", &ipr);
3890       fscanf(fp, "%f", &st);
3891       fscanf(fp, "%f", &intensity);
3892       fscanf(fp, "%f %f %f %f", &m11, &m12, &m13, &m14);
3893       fscanf(fp, "%f %f %f %f", &m21, &m22, &m23, &m24);
3894       fscanf(fp, "%f %f %f %f", &m31, &m32, &m33, &m34);
3895       fscanf(fp, "%f %f %f %f", &m41, &m42, &m43, &m44);
3896       fclose(fp);
3897 
3898       if((fp = fopen(analyse_fname, "r")) != NULL)
3899         {
3900 
3901           fscanf(fp, "%s", t1_path);
3902           fscanf(fp, "%s", fname_descrip);
3903           fscanf(fp, "%d %d", &nslices, &nt);
3904           fscanf(fp, "%d %d", &nx, &ny);
3905           fclose(fp);
3906 
3907           if(read_volume)
3908             {
3909               mri = MRIallocSequence(nx, ny, nslices, MRI_SHORT, nt);
3910             }
3911           else
3912             {
3913               mri = MRIallocHeader(nx, ny, nslices, MRI_SHORT);
3914               mri->nframes = nt;
3915             }
3916 
3917           strcpy(mri->fname, fname_passed);
3918           mri->imnr0 = 1;
3919           mri->imnr1 = nslices;
3920           mri->xsize = mri->ysize = mri->ps = ipr;
3921           mri->zsize = mri->thick = st;
3922 
3923           fov_x = mri->xsize * mri->width;
3924           fov_y = mri->ysize * mri->height;
3925           fov_z = mri->zsize * mri->depth;
3926 
3927           mri->fov = (fov_x > fov_y ? (fov_x > fov_z ? fov_x : fov_z) :
3928                       (fov_y > fov_z ? fov_y : fov_z));
3929 
3930           mri->xend = fov_x / 2.0;
3931           mri->xstart = -mri->xend;
3932           mri->yend = fov_y / 2.0;
3933           mri->ystart = -mri->yend;
3934           mri->zend = fov_z / 2.0;
3935           mri->zstart = -mri->zend;
3936 
3937           mri->brightness = intensity;
3938           strcpy(mri->subject_name, sn);
3939           strcpy(mri->path_to_t1, t1_path);
3940           strcpy(mri->fname_format, fname_descrip);
3941 
3942           m = MatrixAlloc(4, 4, MATRIX_REAL);
3943           if(m == NULL)
3944             {
3945               MRIfree(&mri);
3946               errno = 0;
3947               ErrorReturn(NULL, (ERROR_NO_MEMORY, "error allocating "
3948                                  "matrix in %s read", extension));
3949             }
3950           stuff_four_by_four(m, m11, m12, m13, m14,
3951                              m21, m22, m23, m24,
3952                              m31, m32, m33, m34,
3953                              m41, m42, m43, m44);
3954           mri->register_mat = m;
3955           res = orient_with_register(mri);
3956           if(res != NO_ERROR){
3957             MRIfree(&mri);
3958             return(NULL);
3959           }
3960           return(mri);
3961         }
3962     }
3963 #endif
3964 
3965   mri = MRIallocHeader(1, 1, 1, type);
3966 
3967   /* ----- try to read the stem.bhdr ----- */
3968   sprintf(bhdr_name, "%s/%s.bhdr", directory, stem);
3969   if((fp = fopen(bhdr_name, "r")) != NULL)
3970     {
3971       read_bhdr(mri, fp);
3972       sprintf(fname, "%s/%s_000.hdr", directory, stem);
3973       if((fp = fopen(fname, "r")) == NULL){
3974         MRIfree(&mri);
3975         errno = 0;
3976         ErrorReturn(NULL, (ERROR_BADFILE, "cannot open %s", fname));
3977       }
3978       fscanf(fp, "%d %d %d %*d", &ny, &nx, &nt);
3979       mri->nframes = nt;
3980       fclose(fp);
3981     }
3982   else
3983     { /* ----- get defaults ----- */
3984       fprintf
3985         (stderr,
3986          "-----------------------------------------------------------------\n"
3987          "Could not find the direction cosine information.\n"
3988          "Will use the CORONAL orientation.\n"
3989          "If not suitable, please provide the information in %s file\n"
3990          "-----------------------------------------------------------------\n",
3991          bhdr_name);
3992       sprintf(fname, "%s/%s_000.hdr", directory, stem);
3993       if((fp = fopen(fname, "r")) == NULL)
3994         {
3995           MRIfree(&mri);
3996           errno = 0;
3997           ErrorReturn(NULL, (ERROR_BADFILE, "can't find file %s (last resort);"
3998                              "bailing out on read", fname));
3999         }
4000       fscanf(fp, "%d %d %d %*d", &ny, &nx, &nt);
4001       fclose(fp);
4002 
4003       /* --- get the number of slices --- */
4004       sprintf(fname, "%s/%s_000.%s", directory, stem, extension);
4005       if(!FileExists(fname)){
4006         MRIfree(&mri);
4007         errno = 0;
4008         ErrorReturn(NULL, (ERROR_BADFILE, "can't find file %s; "
4009                            "bailing out on read", fname));
4010       }
4011       for(nslices = 0;FileExists(fname);nslices++)
4012         sprintf(fname, "%s/%s_%03d.%s", directory, stem, nslices, extension);
4013       nslices--;
4014 
4015       mri->width   = nx;
4016       mri->height  = ny;
4017       mri->depth   = nslices;
4018       mri->nframes = nt;
4019 
4020       mri->imnr0 = 1;
4021       mri->imnr1 = nslices;
4022 
4023       mri->thick = mri->ps = 1.0;
4024       mri->xsize = mri->ysize = mri->zsize = 1.0;
4025 
4026       setDirectionCosine(mri, MRI_CORONAL);
4027 
4028       mri->ras_good_flag = 0;
4029 
4030       strcpy(mri->fname, fname_passed);
4031 
4032     }
4033 
4034   mri->imnr0 = 1;
4035   mri->imnr1 = nslices;
4036 
4037   mri->xend = mri->width  * mri->xsize / 2.0;
4038   mri->xstart = -mri->xend;
4039   mri->yend = mri->height * mri->ysize / 2.0;
4040   mri->ystart = -mri->yend;
4041   mri->zend = mri->depth  * mri->zsize / 2.0;
4042   mri->zstart = -mri->zend;
4043 
4044   mri->fov = ((mri->xend - mri->xstart) > (mri->yend - mri->ystart) ?
4045               (mri->xend - mri->xstart) : (mri->yend - mri->ystart));
4046 
4047 
4048   if(read_volume)
4049     {
4050       mri2 = MRIallocSequence(mri->width, mri->height, mri->depth,
4051                               mri->type, mri->nframes);
4052       MRIcopyHeader(mri, mri2);
4053       MRIfree(&mri);
4054       mri = mri2;
4055     }
4056 
4057   return(mri);
4058 
4059 } /* end get_b_info() */
4060 
4061 /*-------------------------------------------------------------------
4062   bvolumeRead() - this replaces bshortRead and bfloatRead.
4063   -------------------------------------------------------------------*/
4064 static MRI *bvolumeRead(char *fname_passed, int read_volume, int type)
4065 {
4066 
4067   MRI *mri;
4068   FILE *fp;
4069   char fname[STRLEN];
4070   char directory[STRLEN];
4071   char stem[STRLEN];
4072   int swap_bytes_flag;
4073   int slice, frame, row, k;
4074   int nread;
4075   char *ext;
4076   int size;
4077   float min, max;
4078 
4079   /* check the type and set the extension and size*/
4080   switch(type) {
4081   case MRI_SHORT: ext = "bshort"; size = sizeof(short); break;
4082   case MRI_FLOAT: ext = "bfloat"; size = sizeof(float); break;
4083   default:
4084     fprintf(stderr,"ERROR: bvolumeRead: type (%d) is not "
4085             "short or float\n", type);
4086     return(NULL);
4087   }
4088 
4089   /* Get the header info (also allocs if needed) */
4090   mri = get_b_info(fname_passed, read_volume, directory, stem, type);
4091   if(mri == NULL) return(NULL);
4092 
4093   /* If not reading the volume, return now */
4094   if(! read_volume) return(mri);
4095 
4096   /* Read in the header of the first slice to get the endianness */
4097   sprintf(fname, "%s/%s_%03d.hdr", directory, stem, 0);
4098   if((fp = fopen(fname, "r")) == NULL){
4099     fprintf(stderr, "ERROR: can't open file %s; assuming big-endian bvolume\n",
4100             fname);
4101     swap_bytes_flag = 0;
4102   }
4103   else{
4104     fscanf(fp, "%*d %*d %*d %d", &swap_bytes_flag);
4105 #if (BYTE_ORDER == LITTLE_ENDIAN)
4106     swap_bytes_flag = !swap_bytes_flag;
4107 #endif
4108     fclose(fp);
4109   }
4110 
4111   /* Go through each slice */
4112   for(slice = 0;slice < mri->depth; slice++){
4113 
4114     /* Open the file for this slice */
4115     sprintf(fname, "%s/%s_%03d.%s", directory, stem, slice, ext);
4116     if((fp = fopen(fname, "r")) == NULL){
4117       MRIfree(&mri);
4118       errno = 0;
4119       ErrorReturn(NULL, (ERROR_BADFILE,
4120                          "bvolumeRead(): error opening file %s", fname));
4121     }
4122     //fprintf(stderr, "Reading %s ... \n", fname);
4123     /* Loop through the frames */
4124     for(frame = 0; frame < mri->nframes; frame ++){
4125       k = slice + mri->depth*frame;
4126 
4127       /* Loop through the rows */
4128       for(row = 0;row < mri->height; row++){
4129 
4130         /* read in all the columns for a row */
4131         nread = fread(mri->slices[k][row], size, mri->width, fp);
4132         if( nread != mri->width){
4133           fclose(fp);
4134           MRIfree(&mri);
4135           errno = 0;
4136           ErrorReturn(NULL, (ERROR_BADFILE, "bvolumeRead(): "
4137                              "error reading from file %s", fname));
4138         }
4139 
4140         if(swap_bytes_flag){
4141           if(type == MRI_SHORT)
4142             swab(mri->slices[k][row], mri->slices[k][row], mri->width * size);
4143           else
4144             byteswapbuffloat((void*)mri->slices[k][row],size*mri->width);
4145         }
4146       } /* row loop */
4147     } /* frame loop */
4148 
4149     fclose(fp);
4150   } /* slice loop */
4151 
4152   MRIlimits(mri,&min,&max);
4153   printf("INFO: bvolumeRead: min = %g, max = %g\n",min,max);
4154 
4155   mri->imnr0 = 1;
4156   mri->imnr1 = mri->depth;
4157   mri->thick = mri->zsize;
4158 
4159   return(mri);
4160 
4161 } /* end bvolumeRead() */
4162 
4163 
4164 #if 0
4165 static int orient_with_register(MRI *mri)
4166 {
4167 
4168   MRI *subject_mri;
4169   char *subjects_dir;
4170   char subject_directory[STRLEN];
4171   MATRIX *sa, *fa;
4172   MATRIX *sr, *fr;
4173   MATRIX *rinv, *sainv;
4174   MATRIX *r1, *r2;
4175   int res;
4176   float det;
4177 
4178   subject_mri = NULL;
4179   if((subjects_dir = getenv("SUBJECTS_DIR")) != NULL)
4180     {
4181       sprintf
4182         (subject_directory, "%s/%s/mri/T1", subjects_dir, mri->subject_name);
4183       if((subject_mri = MRIreadInfo(subject_directory)) == NULL)
4184         {
4185           errno = 0;
4186           ErrorPrintf
4187             (ERROR_BADPARM,
4188              "can't get get information from %s; ", subject_directory);
4189           sprintf
4190             (subject_directory,
4191              "%s/%s/mri/T1", subjects_dir, mri->subject_name);
4192           ErrorPrintf
4193             (ERROR_BADPARM, "trying %s instead...\n", subject_directory);
4194           if((subject_mri = MRIreadInfo(subject_directory)) == NULL)
4195             ErrorPrintf
4196               (ERROR_BADPARM,
4197                "can't get information from %s\n", subject_directory);
4198         }
4199     }
4200   else
4201     {
4202       errno = 0;
4203       ErrorPrintf
4204         (ERROR_BADPARM, "can't get environment variable SUBJECTS_DIR");
4205     }
4206 
4207   if(subject_mri == NULL)
4208     {
4209 
4210       errno = 0;
4211       ErrorPrintf(ERROR_BADPARM, "guessing at COR- orientation...\n");
4212 
4213       subject_mri = MRIallocHeader(256, 256, 256, MRI_UCHAR);
4214       subject_mri->fov = 256.0;
4215       subject_mri->thick = subject_mri->ps = 1.0;
4216       subject_mri->xsize = subject_mri->ysize = subject_mri->zsize = 1.0;
4217       setDirectionCosine(subject_mri, MRI_CORONAL);
4218       subject_mri->ras_good_flag = 1;
4219     }
4220 
4221   det = MatrixDeterminant(mri->register_mat);
4222   if(det == 0.0)
4223     {
4224       MRIfree(&subject_mri);
4225       errno = 0;
4226       ErrorPrintf
4227         (ERROR_BADPARM,
4228          "orient_with_register(): registration matrix has zero determinant");
4229       ErrorPrintf(ERROR_BADPARM, "matrix is:");
4230       MatrixPrint(stderr, mri->register_mat);
4231       return(ERROR_BADPARM);
4232     }
4233 
4234   rinv = MatrixInverse(mri->register_mat, NULL);
4235 
4236   if(rinv == NULL)
4237     {
4238       MRIfree(&subject_mri);
4239       errno = 0;
4240       ErrorPrintf
4241         (ERROR_BADPARM,
4242          "orient_with_register(): error inverting registration matrix");
4243       ErrorPrintf(ERROR_BADPARM, "matrix is:");
4244       MatrixPrint(stderr, mri->register_mat);
4245       return(ERROR_BADPARM);
4246     }
4247 
4248   sr = extract_i_to_r(subject_mri);
4249 
4250   sa = MatrixAlloc(4, 4, MATRIX_REAL);
4251   fa = MatrixAlloc(4, 4, MATRIX_REAL);
4252 
4253   if(sr == NULL || sa == NULL || fa == NULL)
4254     {
4255       if(sr != NULL)
4256         MatrixFree(&sr);
4257       if(sa != NULL)
4258         MatrixFree(&sa);
4259       if(fa != NULL)
4260         MatrixFree(&fa);
4261       MatrixFree(&rinv);
4262       MRIfree(&subject_mri);
4263       errno = 0;
4264       ErrorReturn
4265         (ERROR_NO_MEMORY,
4266          (ERROR_NO_MEMORY,
4267           "orient_with_register(): error allocating matrix"));
4268     }
4269 
4270   stuff_four_by_four
4271     (sa, -subject_mri->xsize, 0.0, 0.0, subject_mri->width * subject_mri->xsize / 2.0,
4272      0.0, 0.0, subject_mri->zsize, -subject_mri->depth * subject_mri->zsize / 2.0,
4273      0.0, -subject_mri->ysize, 0.0, subject_mri->height * subject_mri->ysize / 2.0,
4274      0.0, 0.0, 0.0, 1.0);
4275 
4276   MRIfree(&subject_mri);
4277 
4278   stuff_four_by_four(fa, -mri->xsize, 0.0, 0.0, mri->width * mri->xsize / 2.0,
4279                      0.0, 0.0, mri->zsize, -mri->depth * mri->zsize / 2.0,
4280                      0.0, -mri->ysize, 0.0, mri->height * mri->ysize / 2.0,
4281                      0.0, 0.0, 0.0, 1.0);
4282   det = MatrixDeterminant(sa);
4283   if(det == 0.0)
4284     {
4285       MatrixFree(&sr);
4286       MatrixFree(&sa);
4287       MatrixFree(&fa);
4288       MatrixFree(&rinv);
4289       errno = 0;
4290       ErrorPrintf(ERROR_BADPARM,
4291                   "orient_with_register(): destination (ijk) -> r "
4292                   "space matrix has zero determinant");
4293       ErrorPrintf(ERROR_BADPARM, "matrix is:");
4294       MatrixPrint(stderr, sa);
4295       return(ERROR_BADPARM);
4296     }
4297 
4298   sainv = MatrixInverse(sa, NULL);
4299   MatrixFree(&sa);
4300 
4301   if(sainv == NULL)
4302     {
4303       MatrixFree(&sr);
4304       MatrixFree(&sa);
4305       MatrixFree(&fa);
4306       MatrixFree(&rinv);
4307       errno = 0;
4308       ErrorPrintf
4309         (ERROR_BADPARM,
4310          "orient_with_register(): error inverting "
4311          "destination (ijk) -> r space matrix");
4312       ErrorPrintf(ERROR_BADPARM, "matrix is:");
4313       MatrixPrint(stderr, sainv);
4314       return(ERROR_BADPARM);
4315     }
4316 
4317   r1 = MatrixMultiply(rinv, fa, NULL);
4318   MatrixFree(&rinv);
4319   MatrixFree(&fa);
4320   if(r1 == NULL)
4321     {
4322       MatrixFree(&sr);
4323       MatrixFree(&sa);
4324       MatrixFree(&sainv);
4325       errno = 0;
4326       ErrorReturn(ERROR_BADPARM,
4327                   (ERROR_BADPARM,
4328                    "orient_with_register(): error multiplying matrices"));
4329     }
4330 
4331   r2 = MatrixMultiply(sainv, r1, NULL);
4332   MatrixFree(&r1);
4333   MatrixFree(&sainv);
4334   if(r2 == NULL)
4335     {
4336       MatrixFree(&sr);
4337       MatrixFree(&sa);
4338       errno = 0;
4339       ErrorReturn(ERROR_BADPARM,
4340                   (ERROR_BADPARM,
4341                    "orient_with_register(): error multiplying matrices"));
4342     }
4343 
4344   fr = MatrixMultiply(sr, r2, NULL);
4345   MatrixFree(&sr);
4346   MatrixFree(&r2);
4347   if(fr == NULL)
4348     {
4349       errno = 0;
4350       ErrorReturn(ERROR_BADPARM,
4351                   (ERROR_BADPARM,
4352                    "orient_with_register(): error multiplying matrices"));
4353     }
4354 
4355   res = apply_i_to_r(mri, fr);
4356   MatrixFree(&fr);
4357 
4358   if(res != NO_ERROR)
4359     return(res);
4360 
4361   return(NO_ERROR);
4362 
4363 } /* end orient_with_register() */
4364 #endif
4365 
4366 int decompose_b_fname(char *fname, char *dir, char *stem)
4367 {
4368 
4369   char *slash, *dot, *stem_start, *underscore;
4370   int fname_length;
4371   int und_pos;
4372   char fname_copy[STRLEN];
4373 
4374   /*
4375 
4376   options for file names:
4377 
4378   stem_xxx.bshort
4379   stem_xxx
4380   stem_.bshort
4381   stem_
4382   stem.bshort
4383   stem
4384 
4385   with or without a preceding directory
4386 
4387   */
4388 
4389   strcpy(fname_copy, fname);
4390 
4391   slash = strrchr(fname_copy, '/');
4392   dot = strrchr(fname_copy, '.');
4393   underscore = strrchr(fname_copy, '_');
4394 
4395   if(slash == NULL)
4396     {
4397       stem_start = fname_copy;
4398       sprintf(dir, ".");
4399     }
4400   else
4401     {
4402       *slash = '\0';
4403       strcpy(dir, fname_copy);
4404       stem_start = slash + 1;
4405     }
4406 
4407   if(*stem_start == '\0')
4408     {
4409       errno = 0;
4410       ErrorReturn
4411         (ERROR_BADPARM,
4412          (ERROR_BADPARM,
4413           "decompose_b_fname(): bad bshort/bfloat file specifier \"%s\"",
4414           fname));
4415     }
4416 
4417   if(dot != NULL)
4418     if(strcmp(dot, ".bshort") == 0 || strcmp(dot, ".bfloat") == 0)
4419       *dot = '\0';
4420 
4421   fname_length = strlen(stem_start);
4422 
4423   if(underscore == NULL)
4424     strcpy(stem, stem_start);
4425   else
4426     {
4427       und_pos = (underscore - stem_start);
4428       if(und_pos == fname_length - 1 || und_pos == fname_length - 4)
4429         *underscore = '\0';
4430       strcpy(stem, stem_start);
4431     }
4432 
4433   return(NO_ERROR);
4434 
4435 } /* end decompose_b_fname() */
4436 
4437 /*-------------------------------------------------------------*/
4438 static int write_bhdr(MRI *mri, FILE *fp)
4439 {
4440   float vl;            /* vector length */
4441   float tlr, tla, tls; /* top left coordinates */
4442   float trr, tra, trs; /* top right coordinates */
4443   float brr, bra, brs; /* bottom right coordinates */
4444   float nr, na, ns;    /* normal coordinates */
4445   MATRIX *T, *crs1, *ras1;
4446 
4447   crs1 = MatrixAlloc(4,1,MATRIX_REAL);
4448   crs1->rptr[1][4] = 1;
4449   ras1 = MatrixAlloc(4,1,MATRIX_REAL);
4450 
4451   /* Construct the matrix to convert CRS to XYZ, assuming
4452      that CRS is 1-based */
4453   T = MRIxfmCRS2XYZ(mri,0);
4454   //printf("------- write_bhdr: T ---------\n");
4455   //MatrixPrint(stdout,T);
4456   //printf("------------------------------\n");
4457 
4458   /* The "top left" is the center of the first voxel */
4459   tlr = T->rptr[1][4];
4460   tla = T->rptr[2][4];
4461   tls = T->rptr[3][4];
4462 
4463   /* The "top right" is the center of the last voxel + 1 in the
4464      column direction - this unfortunate situation is historical.
4465      It makes the difference between the TL and TR equal to the
4466      edge-to-edge FOV in the column direction. */
4467   crs1->rptr[1][1] = mri->width;
4468   crs1->rptr[1][2] = 0;
4469   crs1->rptr[1][3] = 0;
4470   MatrixMultiply(T,crs1,ras1);
4471   trr = ras1->rptr[1][1];
4472   tra = ras1->rptr[1][2];
4473   trs = ras1->rptr[1][3];
4474 
4475   /* The "bottom right" is the center of the last voxel + 1 in the
4476      column and row directions - this unfortunate situation is
4477      historical. It makes the difference between the TR and BR equal
4478      to the edge-to-edge FOV in the row direction. */
4479   crs1->rptr[1][1] = mri->width;
4480   crs1->rptr[1][2] = mri->height;
4481   crs1->rptr[1][3] = 0;
4482   MatrixMultiply(T,crs1,ras1);
4483   brr = ras1->rptr[1][1];
4484   bra = ras1->rptr[1][2];
4485   brs = ras1->rptr[1][3];
4486 
4487   MatrixFree(&T);
4488   MatrixFree(&crs1);
4489   MatrixFree(&ras1);
4490 
4491   /* ----- normalize this just in case ----- */
4492   vl = sqrt(mri->z_r*mri->z_r + mri->z_a*mri->z_a + mri->z_s*mri->z_s);
4493   nr = mri->z_r / vl;
4494   na = mri->z_a / vl;
4495   ns = mri->z_s / vl;
4496 
4497 #if 0
4498   time_t time_now;
4499   float cr, ca, cs;    /* first slice center coordinates */
4500   cr = mri->c_r - (mri->depth - 1) / 2.0 * mri->z_r * mri->zsize;
4501   ca = mri->c_a - (mri->depth - 1) / 2.0 * mri->z_a * mri->zsize;
4502   cs = mri->c_s - (mri->depth - 1) / 2.0 * mri->z_s * mri->zsize;
4503 
4504   tlr = cr - mri->width / 2.0 * mri->x_r * mri->xsize - mri->height / 2.0 *
4505     mri->y_r * mri->ysize;
4506   tla = ca - mri->width / 2.0 * mri->x_a * mri->xsize - mri->height / 2.0 *
4507     mri->y_a * mri->ysize;
4508   tls = cs - mri->width / 2.0 * mri->x_s * mri->xsize - mri->height / 2.0 *
4509     mri->y_s * mri->ysize;
4510 
4511   trr = cr + mri->width / 2.0 * mri->x_r * mri->xsize - mri->height / 2.0 *
4512     mri->y_r * mri->ysize;
4513   tra = ca + mri->width / 2.0 * mri->x_a * mri->xsize - mri->height / 2.0 *
4514     mri->y_a * mri->ysize;
4515   trs = cs + mri->width / 2.0 * mri->x_s * mri->xsize - mri->height / 2.0 *
4516     mri->y_s * mri->ysize;
4517 
4518   brr = cr + mri->width / 2.0 * mri->x_r * mri->xsize + mri->height / 2.0 *
4519     mri->y_r * mri->ysize;
4520   bra = ca + mri->width / 2.0 * mri->x_a * mri->xsize + mri->height / 2.0 *
4521     mri->y_a * mri->ysize;
4522   brs = cs + mri->width / 2.0 * mri->x_s * mri->xsize + mri->height / 2.0 *
4523     mri->y_s * mri->ysize;
4524 
4525   time(&time_now);
4526 
4527   //fprintf(fp, "bhdr generated by %s\n", Progname);
4528   //fprintf(fp, "%s\n", ctime(&time_now));
4529   //fprintf(fp, "\n");
4530 #endif
4531 
4532   fprintf(fp, "          cols: %d\n", mri->width);
4533   fprintf(fp, "          rows: %d\n", mri->height);
4534   fprintf(fp, "       nslices: %d\n", mri->depth);
4535   fprintf(fp, " n_time_points: %d\n", mri->nframes);
4536   fprintf(fp, "   slice_thick: %f\n", mri->zsize);
4537   fprintf(fp, "    top_left_r: %f\n", tlr);
4538   fprintf(fp, "    top_left_a: %f\n", tla);
4539   fprintf(fp, "    top_left_s: %f\n", tls);
4540   fprintf(fp, "   top_right_r: %f\n", trr);
4541   fprintf(fp, "   top_right_a: %f\n", tra);
4542   fprintf(fp, "   top_right_s: %f\n", trs);
4543   fprintf(fp, "bottom_right_r: %f\n", brr);
4544   fprintf(fp, "bottom_right_a: %f\n", bra);
4545   fprintf(fp, "bottom_right_s: %f\n", brs);
4546   fprintf(fp, "      normal_r: %f\n", nr);
4547   fprintf(fp, "      normal_a: %f\n", na);
4548   fprintf(fp, "      normal_s: %f\n", ns);
4549   fprintf(fp, "      image_te: %f\n", mri->te);
4550   fprintf(fp, "      image_tr: %f\n", mri->tr/1000.0); // convert to sec
4551   fprintf(fp, "      image_ti: %f\n", mri->ti);
4552   fprintf(fp, "    flip_angle: %f\n", mri->flip_angle);
4553 
4554   return(NO_ERROR);
4555 
4556 } /* end write_bhdr() */
4557 
4558 /*------------------------------------------------------*/
4559 int read_bhdr(MRI *mri, FILE *fp)
4560 {
4561 
4562   char line[STRLEN];
4563   char *l;
4564   float tlr=0.;
4565   float tla=0.;
4566   float tls=0.; /* top left coordinates */
4567   float trr=0.;
4568   float tra=0.;
4569   float trs=0.; /* top right coordinates */
4570   float brr=0.;
4571   float bra=0.;
4572   float brs=0.; /* bottom right coordinates */
4573   float xr=0.;
4574   float xa=0.;
4575   float xs=0.;
4576   float yr=0.;
4577   float ya=0.;
4578   float ys=0.;
4579   MATRIX *T, *CRSCenter, *RASCenter;
4580 
4581   while(1){  // don't use   "while (!feof(fp))"
4582 
4583     /* --- read the line --- */
4584     fgets(line, STRLEN, fp);
4585 
4586     if (feof(fp))  // wow, it was beyound the end of the file. get out.
4587       break;
4588 
4589     /* --- remove the newline --- */
4590     if(line[strlen(line)-1] == '\n')
4591       line[strlen(line)-1] = '\0';
4592 
4593     /* --- skip the initial spaces --- */
4594     for(l = line;isspace((int)(*l));l++);
4595 
4596     /* --- get the varible name and value(s) --- */
4597     if(strlen(l) > 0){
4598       if(strncmp(l, "cols: ", 6) == 0)
4599         sscanf(l, "%*s %d", &mri->width);
4600       else if(strncmp(l, "rows: ", 6) == 0)
4601         sscanf(l, "%*s %d", &mri->height);
4602       else if(strncmp(l, "nslices: ", 9) == 0)
4603         sscanf(l, "%*s %d", &mri->depth);
4604       else if(strncmp(l, "n_time_points: ", 15) == 0)
4605         sscanf(l, "%*s %d", &mri->nframes);
4606       else if(strncmp(l, "slice_thick: ", 13) == 0)
4607         sscanf(l, "%*s %f", &mri->zsize);
4608       else if(strncmp(l, "image_te: ", 10) == 0)
4609         sscanf(l, "%*s %f", &mri->te);
4610       else if(strncmp(l, "image_tr: ", 10) == 0){
4611         sscanf(l, "%*s %f", &mri->tr);
4612         mri->tr = 1000.0 * mri->tr; // convert from sec to msec
4613       }
4614       else if(strncmp(l, "image_ti: ", 10) == 0)
4615         sscanf(l, "%*s %f", &mri->ti);
4616       else if(strncmp(l, "flip_angle: ", 10) == 0)
4617         sscanf(l, "%*s %lf", &mri->flip_angle);
4618       else if(strncmp(l, "top_left_r: ", 12) == 0)
4619         sscanf(l, "%*s %g", &tlr);
4620       else if(strncmp(l, "top_left_a: ", 12) == 0)
4621         sscanf(l, "%*s %g", &tla);
4622       else if(strncmp(l, "top_left_s: ", 12) == 0)
4623         sscanf(l, "%*s %g", &tls);
4624       else if(strncmp(l, "top_right_r: ", 13) == 0)
4625         sscanf(l, "%*s %g", &trr);
4626       else if(strncmp(l, "top_right_a: ", 13) == 0)
4627         sscanf(l, "%*s %g", &tra);
4628       else if(strncmp(l, "top_right_s: ", 13) == 0)
4629         sscanf(l, "%*s %g", &trs);
4630       else if(strncmp(l, "bottom_right_r: ", 16) == 0)
4631         sscanf(l, "%*s %g", &brr);
4632       else if(strncmp(l, "bottom_right_a: ", 16) == 0)
4633         sscanf(l, "%*s %g", &bra);
4634       else if(strncmp(l, "bottom_right_s: ", 16) == 0)
4635         sscanf(l, "%*s %g", &brs);
4636       else if(strncmp(l, "normal_r: ", 10) == 0)
4637         sscanf(l, "%*s %g", &mri->z_r);
4638       else if(strncmp(l, "normal_a: ", 10) == 0)
4639         sscanf(l, "%*s %g", &mri->z_a);
4640       else if(strncmp(l, "normal_s: ", 10) == 0)
4641         sscanf(l, "%*s %g", &mri->z_s);
4642       else { /* --- ignore it --- */ }
4643     }
4644   } /* end while(!feof()) */
4645   // forget to close file
4646   fclose(fp);
4647 
4648   //  vox to ras matrix is
4649   //
4650   //  Xr*Sx  Yr*Sy  Zr*Sz  Tr
4651   //  Xa*Sx  Ya*Sy  Za*Sz  Ta
4652   //  Xs*Sx  Ys*Sy  Zs*Sz  Ts
4653   //    0      0      0    1
4654   //
4655   //  Therefore
4656   //
4657   //  trr = Xr*Sx*W + Tr, tlr = Tr
4658   //  tra = Xa*Sx*W + Ta, tla = Ta
4659   //  trs = Xs*Sx*W + Ts, tls = Ts
4660   //
4661   //  Thus
4662   //
4663   //  Sx = sqrt ( ((trr-tlr)/W)^2 + ((tra-tla)/W)^2 + ((trs-tls)/W)^2)
4664   //     since Xr^2 + Xa^2 + Xs^2 = 1
4665   //  Xr = (trr-tlr)/(W*Sx)
4666   //  Xa = (tra-tla)/(W*Sx)
4667   //  Xs = (trs-tls)/(W*Sx)
4668   //
4669   //  Similar things for others
4670   //
4671   xr = (trr - tlr) / mri->width;
4672   xa = (tra - tla) / mri->width;
4673   xs = (trs - tls) / mri->width;
4674   mri->xsize = sqrt(xr*xr + xa*xa + xs*xs);
4675   if (mri->xsize) // avoid nan
4676     {
4677       mri->x_r = xr / mri->xsize;
4678       mri->x_a = xa / mri->xsize;
4679       mri->x_s = xs / mri->xsize;
4680     }
4681   else // fake values
4682     {
4683       mri->xsize = 1;
4684       mri->x_r = -1;
4685       mri->x_a = 0;
4686       mri->x_s = 0;
4687     }
4688   yr = (brr - trr) / mri->height;
4689   ya = (bra - tra) / mri->height;
4690   ys = (brs - trs) / mri->height;
4691   mri->ysize = sqrt(yr*yr + ya*ya + ys*ys);
4692   if (mri->ysize) // avoid nan
4693     {
4694       mri->y_r = yr / mri->ysize;
4695       mri->y_a = ya / mri->ysize;
4696       mri->y_s = ys / mri->ysize;
4697     }
4698   else // fake values
4699     {
4700       mri->ysize = 1;
4701       mri->y_r = 0;
4702       mri->y_a = 0;
4703       mri->y_s = -1;
4704     }
4705   T = MRIxfmCRS2XYZ(mri,0);
4706 
4707   T->rptr[1][4] = tlr;
4708   T->rptr[2][4] = tla;
4709   T->rptr[3][4] = tls;
4710 
4711   //printf("------- read_bhdr: T ---------\n");
4712   //MatrixPrint(stdout,T);
4713   //printf("------------------------------\n");
4714 
4715   CRSCenter = MatrixAlloc(4,1,MATRIX_REAL);
4716   CRSCenter->rptr[1][1] = (mri->width)/2.0;
4717   CRSCenter->rptr[2][1] = (mri->height)/2.0;
4718   CRSCenter->rptr[3][1] = (mri->depth)/2.0;
4719   CRSCenter->rptr[4][1] = 1;
4720 
4721   RASCenter = MatrixMultiply(T,CRSCenter,NULL);
4722   mri->c_r = RASCenter->rptr[1][1];
4723   mri->c_a = RASCenter->rptr[2][1];
4724   mri->c_s = RASCenter->rptr[3][1];
4725 
4726   MatrixFree(&T);
4727   MatrixFree(&CRSCenter);
4728   MatrixFree(&RASCenter);
4729 
4730 #if 0
4731   /* This computation of the center is incorrect because TL is the center of
4732      the first voxel (not the edge of the FOV). TR and BR are actually
4733      outside of the FOV.  */
4734   mri->c_r =
4735     (brr + tlr) / 2.0 + (mri->depth - 1) * mri->z_r * mri->zsize / 2.0 ;
4736   mri->c_a =
4737     (bra + tla) / 2.0 + (mri->depth - 1) * mri->z_a * mri->zsize / 2.0 ;
4738   mri->c_s =
4739     (brs + tls) / 2.0 + (mri->depth - 1) * mri->z_s * mri->zsize / 2.0 ;
4740 #endif
4741 
4742   mri->ras_good_flag = 1;
4743 
4744   mri->thick = mri->zsize;
4745   mri->ps = mri->xsize;
4746 
4747   return(NO_ERROR);
4748 
4749 } /* end read_bhdr() */
4750 
4751 
4752 static MRI *genesisRead(char *fname, int read_volume)
4753 {
4754   char fname_format[STRLEN];
4755   char fname_format2[STRLEN];
4756   char fname_dir[STRLEN];
4757   char fname_base[STRLEN];
4758   char *c;
4759   MRI *mri = NULL;
4760   int im_init;
4761   int im_low, im_high;
4762   int im_low2, im_high2;
4763   char fname_use[STRLEN];
4764   char temp_string[STRLEN];
4765   FILE *fp;
4766   int width, height;
4767   int pixel_data_offset;
4768   int image_header_offset;
4769   float tl_r, tl_a, tl_s;
4770   float tr_r, tr_a, tr_s;
4771   float br_r, br_a, br_s;
4772   float c_r, c_a, c_s;
4773   float n_r, n_a, n_s;
4774   float xlength, ylength, zlength;
4775   int i, y;
4776   MRI *header;
4777   float xfov, yfov, zfov;
4778   float nlength;
4779   int twoformats = 0, odd_only, even_only ;
4780 
4781   odd_only = even_only = 0 ;
4782   if (getenv("GE_ODD"))
4783     {
4784       odd_only = 1 ;
4785       printf("only using odd # GE files\n") ;
4786     }
4787   else if (getenv("GE_EVEN"))
4788     {
4789       even_only = 1 ;
4790       printf("only using even # GE files\n") ;
4791     }
4792 
4793   /* ----- check the first (passed) file ----- */
4794   if(!FileExists(fname))
4795     {
4796       errno = 0;
4797       ErrorReturn
4798         (NULL,
4799          (ERROR_BADFILE, "genesisRead(): error opening file %s", fname));
4800     }
4801 
4802   /* ----- split the file name into name and directory ----- */
4803   c = strrchr(fname, '/');
4804   if(c == NULL)
4805     {
4806       fname_dir[0] = '\0';
4807       strcpy(fname_base, fname);
4808     }
4809   else
4810     {
4811       strncpy(fname_dir, fname, (c - fname + 1));
4812       fname_dir[c-fname+1] = '\0';
4813       strcpy(fname_base, c+1);
4814     }
4815 
4816   /* ----- derive the file name format (for sprintf) ----- */
4817   // this one fix fname_format only
4818   if(strncmp(fname_base, "I.", 2) == 0)
4819     {
4820       twoformats = 0;
4821       im_init = atoi(&fname_base[2]);
4822       sprintf(fname_format, "I.%%03d");
4823     }
4824   // this one fix both fname_format and fname_format2
4825   else if(strlen(fname_base) >= 3) /* avoid core dumps below... */
4826     {
4827       twoformats = 1;
4828       c = &fname_base[strlen(fname_base)-3];
4829       if(strcmp(c, ".MR") == 0)
4830         {
4831           *c = '\0';
4832           for(c--;isdigit(*c) && c >= fname_base;c--);
4833           c++;
4834           im_init = atoi(c);
4835           *c = '\0';
4836           // this is too quick to assume of this type
4837           // another type %s%%03d.MR" must be examined
4838           sprintf(fname_format, "%s%%d.MR", fname_base);
4839           sprintf(fname_format2, "%s%%03d.MR", fname_base);
4840         }
4841       else
4842         {
4843           errno = 0;
4844           ErrorReturn
4845             (NULL,
4846              (ERROR_BADPARM,
4847               "genesisRead(): can't determine file name format for %s",
4848               fname));
4849         }
4850     }
4851   else
4852     {
4853       errno = 0;
4854       ErrorReturn
4855         (NULL,
4856          (ERROR_BADPARM,
4857           "genesisRead(): can't determine file name format for %s", fname));
4858     }
4859 
4860   if (strlen(fname_format) != 0)
4861     {
4862       strcpy(temp_string, fname_format);
4863       sprintf(fname_format, "%s%s", fname_dir, temp_string);
4864       printf("fname_format  : %s\n", fname_format);
4865     }
4866   if (strlen(fname_format2) != 0)
4867     {
4868       strcpy(temp_string, fname_format2);
4869       sprintf(fname_format2, "%s%s", fname_dir, temp_string);
4870       printf("fname_format2 : %s\n", fname_format2);
4871     }
4872   /* ----- find the low and high files ----- */
4873   if (odd_only || even_only)
4874     {
4875       if ((odd_only && ISEVEN(im_init)) ||
4876           (even_only && ISODD(im_init)))
4877         im_init++ ;
4878       im_low = im_init;
4879       do
4880         {
4881           im_low -=2 ;
4882           sprintf(fname_use, fname_format, im_low);
4883         } while(FileExists(fname_use));
4884       im_low += 2 ;
4885 
4886       im_high = im_init;
4887       do
4888         {
4889           im_high += 2 ;
4890           sprintf(fname_use, fname_format, im_high);
4891         } while(FileExists(fname_use));
4892       im_high -=2;
4893     }
4894   else
4895     {
4896       im_low = im_init;
4897       do
4898         {
4899           im_low--;
4900           sprintf(fname_use, fname_format, im_low);
4901         } while(FileExists(fname_use));
4902       im_low++;
4903 
4904       im_high = im_init;
4905       do
4906         {
4907           im_high++;
4908           sprintf(fname_use, fname_format, im_high);
4909         } while(FileExists(fname_use));
4910       im_high--;
4911     }
4912 
4913   if (twoformats)
4914     {
4915       // now test fname_format2
4916       im_low2 = im_init;
4917       do
4918         {
4919           im_low2--;
4920           sprintf(fname_use, fname_format2, im_low2);
4921         } while(FileExists(fname_use));
4922       im_low2++;
4923 
4924       im_high2 = im_init;
4925       do
4926         {
4927           im_high2++;
4928           sprintf(fname_use, fname_format2, im_high2);
4929         } while(FileExists(fname_use));
4930       im_high2--;
4931     }
4932   else
4933     {
4934       im_high2 = im_low2 = 0;
4935     }
4936   // now decide which one to pick
4937   if ((im_high2-im_low2) > (im_high-im_low))
4938     {
4939       // we have to use fname_format2
4940       strcpy(fname_format, fname_format2);
4941       im_high = im_high2;
4942       im_low = im_low2;
4943     }
4944   // otherwise the same
4945 
4946   /* ----- allocate the mri structure ----- */
4947   header = MRIallocHeader(1, 1, 1, MRI_SHORT);
4948 
4949   if (odd_only || even_only)
4950     header->depth = (im_high - im_low)/2 + 1;
4951   else
4952     header->depth = im_high - im_low + 1;
4953   header->imnr0 = 1;
4954   header->imnr1 = header->depth;
4955 
4956   /* ----- get the header information from the first file ----- */
4957   sprintf(fname_use, fname_format, im_low);
4958   if((fp = fopen(fname_use, "r")) == NULL)
4959     {
4960       MRIfree(&header);
4961       errno = 0;
4962       ErrorReturn
4963         (NULL,
4964          (ERROR_BADFILE, "genesisRead(): error opening file %s\n", fname_use));
4965     }
4966 
4967   fseek(fp, 8, SEEK_SET);
4968   fread(&width, 4, 1, fp);
4969   width = orderIntBytes(width);
4970   fread(&height, 4, 1, fp);
4971   height = orderIntBytes(height);
4972   fseek(fp, 148, SEEK_SET);
4973   fread(&image_header_offset, 4, 1, fp);
4974   image_header_offset = orderIntBytes(image_header_offset);
4975 
4976   header->width = width;
4977   header->height = height;
4978 
4979   strcpy(header->fname, fname);
4980 
4981   fseek(fp, image_header_offset + 26, SEEK_SET);
4982   fread(&(header->thick), 4, 1, fp);
4983   header->thick = orderFloatBytes(header->thick);
4984   header->zsize = header->thick;
4985 
4986   fseek(fp, image_header_offset + 50, SEEK_SET);
4987   fread(&(header->xsize), 4, 1, fp);
4988   header->xsize = orderFloatBytes(header->xsize);
4989   fread(&(header->ysize), 4, 1, fp);
4990   header->ysize = orderFloatBytes(header->ysize);
4991   header->ps = header->xsize;
4992 
4993   /* all in micro-seconds */
4994 #define MICROSECONDS_PER_MILLISECOND 1e3
4995   fseek(fp, image_header_offset + 194, SEEK_SET);
4996   header->tr = freadInt(fp)/MICROSECONDS_PER_MILLISECOND ;
4997   fseek(fp, image_header_offset + 198, SEEK_SET);
4998   header->ti = freadInt(fp)/MICROSECONDS_PER_MILLISECOND  ;
4999   fseek(fp, image_header_offset + 202, SEEK_SET);
5000   header->te = freadInt(fp)/MICROSECONDS_PER_MILLISECOND  ;
5001   fseek(fp, image_header_offset + 254, SEEK_SET);
5002   header->flip_angle = RADIANS(freadShort(fp)) ;  /* was in degrees */
5003   fseek(fp, image_header_offset + 210, SEEK_SET);  // # of echoes
5004   header->nframes = freadShort(fp) ;
5005   if (header->nframes > 1)
5006     {
5007       printf("multi-echo genesis file detected (%d echoes)...\n",
5008              header->nframes) ;
5009     }
5010   else if (header->nframes == 0)
5011     {
5012       printf("zero frames specified in file - setting to 1\n") ;
5013       header->nframes = 1 ;
5014     }
5015 
5016 
5017   fseek(fp, image_header_offset + 130, SEEK_SET);
5018   fread(&c_r,  4, 1, fp);  c_r  = orderFloatBytes(c_r);
5019   fread(&c_a,  4, 1, fp);  c_a  = orderFloatBytes(c_a);
5020   fread(&c_s,  4, 1, fp);  c_s  = orderFloatBytes(c_s);
5021   fread(&n_r,  4, 1, fp);  n_r  = orderFloatBytes(n_r);
5022   fread(&n_a,  4, 1, fp);  n_a  = orderFloatBytes(n_a);
5023   fread(&n_s,  4, 1, fp);  n_s  = orderFloatBytes(n_s);
5024   fread(&tl_r, 4, 1, fp);  tl_r = orderFloatBytes(tl_r);
5025   fread(&tl_a, 4, 1, fp);  tl_a = orderFloatBytes(tl_a);
5026   fread(&tl_s, 4, 1, fp);  tl_s = orderFloatBytes(tl_s);
5027   fread(&tr_r, 4, 1, fp);  tr_r = orderFloatBytes(tr_r);
5028   fread(&tr_a, 4, 1, fp);  tr_a = orderFloatBytes(tr_a);
5029   fread(&tr_s, 4, 1, fp);  tr_s = orderFloatBytes(tr_s);
5030   fread(&br_r, 4, 1, fp);  br_r = orderFloatBytes(br_r);
5031   fread(&br_a, 4, 1, fp);  br_a = orderFloatBytes(br_a);
5032   fread(&br_s, 4, 1, fp);  br_s = orderFloatBytes(br_s);
5033 
5034   nlength = sqrt(n_r*n_r + n_a*n_a + n_s*n_s);
5035   n_r = n_r / nlength;
5036   n_a = n_a / nlength;
5037   n_s = n_s / nlength;
5038 
5039   if (getenv("KILLIANY_SWAP") != NULL)
5040     {
5041       printf("WARNING - swapping normal direction!\n") ;
5042       n_a *= -1 ;
5043     }
5044 
5045   header->x_r = (tr_r - tl_r);
5046   header->x_a = (tr_a - tl_a);
5047   header->x_s = (tr_s - tl_s);
5048   header->y_r = (br_r - tr_r);
5049   header->y_a = (br_a - tr_a);
5050   header->y_s = (br_s - tr_s);
5051 
5052   /* --- normalize -- the normal vector from the file
5053      should have length 1, but just in case... --- */
5054   xlength =
5055     sqrt(header->x_r*header->x_r +
5056          header->x_a*header->x_a +
5057          header->x_s*header->x_s);
5058   ylength =
5059     sqrt(header->y_r*header->y_r +
5060          header->y_a*header->y_a +
5061          header->y_s*header->y_s);
5062   zlength = sqrt(n_r*n_r + n_a*n_a + n_s*n_s);
5063 
5064   header->x_r = header->x_r / xlength;
5065   header->x_a = header->x_a / xlength;
5066   header->x_s = header->x_s / xlength;
5067   header->y_r = header->y_r / ylength;
5068   header->y_a = header->y_a / ylength;
5069   header->y_s = header->y_s / ylength;
5070   header->z_r = n_r / zlength;
5071   header->z_a = n_a / zlength;
5072   header->z_s = n_s / zlength;
5073 
5074   header->c_r = (tl_r + br_r) / 2.0 + n_r *
5075     header->zsize * (header->depth - 1.0) / 2.0;
5076   header->c_a = (tl_a + br_a) / 2.0 + n_a *
5077     header->zsize * (header->depth - 1.0) / 2.0;
5078   header->c_s = (tl_s + br_s) / 2.0 + n_s *
5079     header->zsize * (header->depth - 1.0) / 2.0;
5080 
5081   header->ras_good_flag = 1;
5082 
5083   header->xend = header->xsize * header->width / 2;
5084   header->xstart = -header->xend;
5085   header->yend = header->ysize * header->height / 2;
5086   header->ystart = -header->yend;
5087   header->zend = header->zsize * header->depth / 2;
5088   header->zstart = -header->zend;
5089 
5090   xfov = header->xend - header->xstart;
5091   yfov = header->yend - header->ystart;
5092   zfov = header->zend - header->zstart;
5093 
5094   header->fov =
5095     (xfov > yfov ? (xfov > zfov ? xfov : zfov) : (yfov > zfov ? yfov : zfov));
5096 
5097   fclose(fp);
5098 
5099   if(read_volume)
5100     mri = MRIallocSequence(header->width, header->height,
5101                            header->depth, header->type, header->nframes);
5102   else
5103     mri = MRIallocHeader(header->width, header->height,
5104                          header->depth, header->type);
5105 
5106   MRIcopyHeader(header, mri);
5107   MRIfree(&header);
5108 
5109   /* ----- read the volume if required ----- */
5110   if(read_volume)
5111     {
5112       int slice, frame ;
5113       for(slice = 0, i = im_low;
5114           i <= im_high;
5115           (odd_only || even_only) ? i+=2 : i++, slice++)
5116         {
5117           frame = (i-im_low) % mri->nframes ;
5118           sprintf(fname_use, fname_format, i);
5119           if((fp = fopen(fname_use, "r")) == NULL)
5120             {
5121               MRIfree(&mri);
5122               errno = 0;
5123               ErrorReturn(NULL,
5124                           (ERROR_BADFILE,
5125                            "genesisRead(): error opening file %s", fname_use));
5126             }
5127 
5128           fseek(fp, 4, SEEK_SET);
5129           fread(&pixel_data_offset, 4, 1, fp);
5130           pixel_data_offset = orderIntBytes(pixel_data_offset);
5131           fseek(fp, pixel_data_offset, SEEK_SET);
5132 
5133           for(y = 0;y < mri->height;y++)
5134             {
5135               if(fread(&MRISseq_vox(mri, 0, y, slice, frame),
5136                        sizeof(short), mri->width, fp) != mri->width)
5137                 {
5138                   fclose(fp);
5139                   MRIfree(&mri);
5140                   errno = 0;
5141                   ErrorReturn
5142                     (NULL,
5143                      (ERROR_BADFILE,
5144                       "genesisRead(): error reading from file file %s",
5145                       fname_use));
5146                 }
5147 #if (BYTE_ORDER == LITTLE_ENDIAN)
5148               //swab(mri->slices[slice][y],
5149               // mri->slices[slice][y], 2 * mri->width);
5150               swab(&MRISseq_vox(mri, 0, y, slice, frame),
5151                    &MRISseq_vox(mri, 0, y, slice, frame),
5152                    sizeof(short) * mri->width);
5153 #endif
5154             }
5155 
5156           fclose(fp);
5157 
5158           if (frame != (mri->nframes-1))
5159             slice-- ;
5160         }
5161 
5162     }
5163 
5164   return(mri);
5165 
5166 } /* end genesisRead() */
5167 
5168 static MRI *gelxRead(char *fname, int read_volume)
5169 {
5170 
5171   char fname_format[STRLEN];
5172   char fname_dir[STRLEN];
5173   char fname_base[STRLEN];
5174   char *c;
5175   MRI *mri = NULL;
5176   int im_init;
5177   int im_low, im_high;
5178   char fname_use[STRLEN];
5179   char temp_string[STRLEN];
5180   FILE *fp;
5181   int width, height;
5182   float tl_r, tl_a, tl_s;
5183   float tr_r, tr_a, tr_s;
5184   float br_r, br_a, br_s;
5185   float c_r, c_a, c_s;
5186   float n_r, n_a, n_s;
5187   float xlength, ylength, zlength;
5188   int i, y;
5189   int ecount, scount, icount;
5190   int good_flag;
5191   MRI *header;
5192   float xfov, yfov, zfov;
5193 
5194   /* ----- check the first (passed) file ----- */
5195   if(!FileExists(fname))
5196     {
5197       errno = 0;
5198       ErrorReturn
5199         (NULL, (ERROR_BADFILE, "genesisRead(): error opening file %s", fname));
5200     }
5201 
5202   /* ----- split the file name into name and directory ----- */
5203   c = strrchr(fname, '/');
5204   if(c == NULL)
5205     {
5206       fname_dir[0] = '\0';
5207       strcpy(fname_base, fname);
5208     }
5209   else
5210     {
5211       strncpy(fname_dir, fname, (c - fname + 1));
5212       fname_dir[c-fname+1] = '\0';
5213       strcpy(fname_base, c+1);
5214     }
5215 
5216   ecount = scount = icount = 0;
5217   good_flag = TRUE;
5218   for(c = fname_base;*c != '\0';c++)
5219     {
5220       if(*c == 'e')
5221         ecount++;
5222       else if(*c == 's')
5223         scount++;
5224       else if(*c == 'i')
5225         icount++;
5226       else if(!isdigit(*c))
5227         good_flag = FALSE;
5228     }
5229   if(good_flag && ecount == 1 && scount == 1 && icount == 1)
5230     {
5231       c = strrchr(fname_base, 'i');
5232       im_init = atoi(c+1);
5233       *c = '\0';
5234       sprintf(fname_format, "%si%%d", fname_base);
5235     }
5236   else
5237     {
5238       errno = 0;
5239       ErrorReturn
5240         (NULL,
5241          (ERROR_BADPARM,
5242           "genesisRead(): can't determine file name format for %s", fname));
5243     }
5244 
5245   strcpy(temp_string, fname_format);
5246   sprintf(fname_format, "%s%s", fname_dir, temp_string);
5247 
5248   /* ----- find the low and high files ----- */
5249   im_low = im_init;
5250   do
5251     {
5252       im_low--;
5253       sprintf(fname_use, fname_format, im_low);
5254     } while(FileExists(fname_use));
5255   im_low++;
5256 
5257   im_high = im_init;
5258   do
5259     {
5260       im_high++;
5261       sprintf(fname_use, fname_format, im_high);
5262     } while(FileExists(fname_use));
5263   im_high--;
5264 
5265   /* ----- allocate the mri structure ----- */
5266   header = MRIallocHeader(1, 1, 1, MRI_SHORT);
5267 
5268   header->depth = im_high - im_low + 1;
5269   header->imnr0 = 1;
5270   header->imnr1 = header->depth;
5271 
5272   /* ----- get the header information from the first file ----- */
5273   sprintf(fname_use, fname_format, im_low);
5274   if((fp = fopen(fname_use, "r")) == NULL)
5275     {
5276       errno = 0;
5277       ErrorReturn
5278         (NULL,
5279          (ERROR_BADFILE, "genesisRead(): error opening file %s\n", fname_use));
5280     }
5281 
5282   fseek(fp, 3236, SEEK_SET);
5283   fread(&width, 4, 1, fp);  width = orderIntBytes(width);
5284   fread(&height, 4, 1, fp);  height = orderIntBytes(height);
5285   header->width = width;
5286   header->height = height;
5287 
5288   strcpy(header->fname, fname);
5289 
5290   fseek(fp, 2184 + 28, SEEK_SET);
5291   fread(&(header->thick), 4, 1, fp);
5292   header->thick = orderFloatBytes(header->thick);
5293   header->zsize = header->thick;
5294 
5295   fseek(fp, 2184 + 52, SEEK_SET);
5296   fread(&(header->xsize), 4, 1, fp);
5297   header->xsize = orderFloatBytes(header->xsize);
5298   fread(&(header->ysize), 4, 1, fp);
5299   header->ysize = orderFloatBytes(header->ysize);
5300   header->ps = header->xsize;
5301 
5302   fseek(fp, 2184 + 136, SEEK_SET);
5303   fread(&c_r,  4, 1, fp);  c_r  = orderFloatBytes(c_r);
5304   fread(&c_a,  4, 1, fp);  c_a  = orderFloatBytes(c_a);
5305   fread(&c_s,  4, 1, fp);  c_s  = orderFloatBytes(c_s);
5306   fread(&n_r,  4, 1, fp);  n_r  = orderFloatBytes(n_r);
5307   fread(&n_a,  4, 1, fp);  n_a  = orderFloatBytes(n_a);
5308   fread(&n_s,  4, 1, fp);  n_s  = orderFloatBytes(n_s);
5309   fread(&tl_r, 4, 1, fp);  tl_r = orderFloatBytes(tl_r);
5310   fread(&tl_a, 4, 1, fp);  tl_a = orderFloatBytes(tl_a);
5311   fread(&tl_s, 4, 1, fp);  tl_s = orderFloatBytes(tl_s);
5312   fread(&tr_r, 4, 1, fp);  tr_r = orderFloatBytes(tr_r);
5313   fread(&tr_a, 4, 1, fp);  tr_a = orderFloatBytes(tr_a);
5314   fread(&tr_s, 4, 1, fp);  tr_s = orderFloatBytes(tr_s);
5315   fread(&br_r, 4, 1, fp);  br_r = orderFloatBytes(br_r);
5316   fread(&br_a, 4, 1, fp);  br_a = orderFloatBytes(br_a);
5317   fread(&br_s, 4, 1, fp);  br_s = orderFloatBytes(br_s);
5318 
5319   header->x_r = (tr_r - tl_r);
5320   header->x_a = (tr_a - tl_a);
5321   header->x_s = (tr_s - tl_s);
5322   header->y_r = (br_r - tr_r);
5323   header->y_a = (br_a - tr_a);
5324   header->y_s = (br_s - tr_s);
5325 
5326   /* --- normalize -- the normal vector from the file
5327      should have length 1, but just in case... --- */
5328   xlength = sqrt(header->x_r*header->x_r +
5329                  header->x_a*header->x_a +
5330                  header->x_s*header->x_s);
5331   ylength = sqrt(header->y_r*header->y_r +
5332                  header->y_a*header->y_a +
5333                  header->y_s*header->y_s);
5334   zlength = sqrt(n_r*n_r + n_a*n_a + n_s*n_s);
5335 
5336   header->x_r = header->x_r / xlength;
5337   header->x_a = header->x_a / xlength;
5338   header->x_s = header->x_s / xlength;
5339   header->y_r = header->y_r / ylength;
5340   header->y_a = header->y_a / ylength;
5341   header->y_s = header->y_s / ylength;
5342   header->z_r = n_r / zlength;
5343   header->z_a = n_a / zlength;
5344   header->z_s = n_s / zlength;
5345 
5346   header->c_r = (tl_r + br_r) / 2.0 + n_r *
5347     header->zsize * (header->depth - 1.0) / 2.0;
5348   header->c_a = (tl_a + br_a) / 2.0 + n_a *
5349     header->zsize * (header->depth - 1.0) / 2.0;
5350   header->c_s = (tl_s + br_s) / 2.0 + n_s *
5351     header->zsize * (header->depth - 1.0) / 2.0;
5352 
5353   header->ras_good_flag = 1;
5354 
5355   header->xend = header->xsize * header->width / 2;
5356   header->xstart = -header->xend;
5357   header->yend = header->ysize * header->height / 2;
5358   header->ystart = -header->yend;
5359   header->zend = header->zsize * header->depth / 2;
5360   header->zstart = -header->zend;
5361 
5362   xfov = header->xend - header->xstart;
5363   yfov = header->yend - header->ystart;
5364   zfov = header->zend - header->zstart;
5365 
5366   header->fov =
5367     ( xfov > yfov ? (xfov > zfov ? xfov : zfov) : (yfov > zfov ? yfov : zfov));
5368 
5369   fclose(fp);
5370 
5371   if(read_volume)
5372     mri = MRIalloc
5373       (header->width, header->height, header->depth, MRI_SHORT);
5374   else
5375     mri = MRIallocHeader
5376       (header->width, header->height, header->depth, MRI_SHORT);
5377 
5378   MRIcopyHeader(header, mri);
5379   MRIfree(&header);
5380 
5381   /* ----- read the volume if required ----- */
5382   if(read_volume)
5383     {
5384       for(i = im_low;i <= im_high; i++)
5385         {
5386 
5387           sprintf(fname_use, fname_format, i);
5388           if((fp = fopen(fname_use, "r")) == NULL)
5389             {
5390               MRIfree(&mri);
5391               errno = 0;
5392               ErrorReturn
5393                 (NULL,
5394                  (ERROR_BADFILE,
5395                   "genesisRead(): error opening file %s", fname_use));
5396             }
5397 
5398           fseek(fp, 8432, SEEK_SET);
5399 
5400           for(y = 0;y < mri->height;y++)
5401             {
5402               if(fread(mri->slices[i-im_low][y], 2, mri->width, fp) !=
5403                  mri->width)
5404                 {
5405                   fclose(fp);
5406                   MRIfree(&mri);
5407                   errno = 0;
5408                   ErrorReturn
5409                     (NULL,
5410                      (ERROR_BADFILE,
5411                       "genesisRead(): error reading from file file %s",
5412                       fname_use));
5413                 }
5414 #if (BYTE_ORDER == LITTLE_ENDIAN)
5415               swab(mri->slices[i-im_low][y], mri->slices[i-im_low][y],
5416                    2 * mri->width);
5417 #endif
5418             }
5419 
5420           fclose(fp);
5421 
5422         }
5423 
5424     }
5425 
5426   return(mri);
5427 
5428 } /* end gelxRead() */
5429 
5430 /*----------------------------------------------------------------------
5431   GetSPMStartFrame() - gets an environment variable called
5432   SPM_START_FRAME and uses its value as the number of the first frame
5433   for an SPM series.  If this variable does not exist, then uses  1.
5434   ----------------------------------------------------------------------*/
5435 int GetSPMStartFrame(void)
5436 {
5437   char *s;
5438   int startframe;
5439   s = getenv("SPM_START_FRAME");
5440   if(s == NULL) return(1);
5441   sscanf(s,"%d",&startframe);
5442   printf("Using env var SPM_START_FRAME = %d\n",startframe);
5443 
5444   return(startframe);
5445 }
5446 
5447 
5448 /*-------------------------------------------------------------------------
5449   CountAnalyzeFiles() - counts the number analyze files associated with
5450   the given analyze file name.  The name can take several forms:
5451   stem.img - a single file
5452   stem     - stem. If nzpad < 0, then an extension of .img is implied.
5453   Otherwise, it looks for a series of files named stemXXX.img
5454   where XXX is a zero padded integer. The width of the padding
5455   is controlled by nzpad. The stem is returned in ppstem (unless
5456   ppstem == NULL).
5457   Note: the files must actually exist.
5458   -------------------------------------------------------------------------*/
5459 int CountAnalyzeFiles(char *analyzefname, int nzpad, char **ppstem)
5460 {
5461   int len, ncopy;
5462   char *stem, fmt[1000], fname[1000];
5463   int nfiles, keepcounting, startframe;
5464   FILE *fp;
5465   nfiles = 0;
5466 
5467   len = strlen(analyzefname);
5468 
5469   /* Determine whether the file name has a .img extension */
5470   if(len > 4 && strcmp(&(analyzefname[len-4]),".img")==0){
5471     ncopy = len-4;
5472     nfiles = 1;
5473     if(nzpad >= 0) {
5474       printf("ERROR: CountAnalyzeFiles: file with .img extension specified "
5475              "       with zero pad variable.\n");
5476       return(-1);
5477     }
5478   }
5479   else {
5480     ncopy = len;
5481     if(nzpad < 0) nfiles = 1;
5482   }
5483 
5484   /* Get the stem (ie, everything without the .img */
5485   stem = (char *) calloc(len+1,sizeof(char));
5486   memcpy(stem,analyzefname,ncopy);
5487 
5488   if(ppstem != NULL) *ppstem = stem;
5489 
5490   /* If there's only one file, check that it's there */
5491   if(nfiles == 1){
5492     sprintf(fname,"%s.img",stem);
5493     if(ppstem == NULL) free(stem);
5494     fp = fopen(fname,"r");
5495     if(fp == NULL) return(0);
5496     fclose(fp);
5497     return(1);
5498   }
5499 
5500   /* If there are multiple files, count them, starting at 1 */
5501   sprintf(fmt,"%s%%0%dd.img",stem,nzpad);
5502   keepcounting = 1;
5503   startframe = GetSPMStartFrame();
5504   nfiles = 0;
5505   while(keepcounting){
5506     sprintf(fname,fmt,nfiles+startframe);
5507     fp = fopen(fname,"r");
5508     if(fp == NULL) keepcounting = 0;
5509     else {
5510       fclose(fp);
5511       nfiles ++;
5512     }
5513   }
5514 
5515   if(ppstem == NULL) free(stem);
5516   return(nfiles);
5517 }
5518 /*-------------------------------------------------------------------------*/
5519 static int DumpAnalyzeHeader(FILE *fp, dsr *hdr)
5520 {
5521   fprintf(fp,"Header Key\n");
5522   fprintf(fp,"  sizeof_hdr    %d\n",hdr->hk.sizeof_hdr);
5523   fprintf(fp,"  data_type     %s\n",hdr->hk.data_type);
5524   fprintf(fp,"  db_name       %s\n",hdr->hk.db_name);
5525   fprintf(fp,"  extents       %d\n",hdr->hk.extents);
5526   fprintf(fp,"  session_error %d\n",hdr->hk.session_error);
5527   fprintf(fp,"  regular       %c\n",hdr->hk.regular);
5528   fprintf(fp,"  hkey_un0      %c\n",hdr->hk.hkey_un0);
5529   fprintf(fp,"Image Dimension \n");
5530   fprintf(fp,"  dim %d %d %d %d %d %d %d %d \n",
5531           hdr->dime.dim[0],hdr->dime.dim[1],hdr->dime.dim[2],hdr->dime.dim[3],
5532           hdr->dime.dim[4],hdr->dime.dim[5],hdr->dime.dim[6],hdr->dime.dim[7]);
5533   fprintf(fp,"  pixdim %f %f %f %f %f %f %f %f \n",
5534           hdr->dime.pixdim[0],hdr->dime.pixdim[1],hdr->dime.pixdim[2],
5535           hdr->dime.pixdim[3],hdr->dime.pixdim[4],hdr->dime.pixdim[5],
5536           hdr->dime.pixdim[6],hdr->dime.pixdim[7]);
5537   fprintf(fp,"  vox_units     %s\n",hdr->dime.vox_units);
5538   fprintf(fp,"  cal_units     %s\n",hdr->dime.cal_units);
5539   fprintf(fp,"  datatype      %d\n",hdr->dime.datatype);
5540   fprintf(fp,"  bitpix        %d\n",hdr->dime.bitpix);
5541   fprintf(fp,"  glmax         %g\n",(float)hdr->dime.glmax);
5542   fprintf(fp,"  glmin         %g\n",(float)hdr->dime.glmin);
5543   fprintf(fp,"  orient        %d\n",hdr->hist.orient);
5544 
5545   return(0);
5546 
5547 }
5548 /*-------------------------------------------------------------------------*/
5549 static dsr *ReadAnalyzeHeader(char *hdrfile, int *swap,
5550                               int *mritype, int *bytes_per_voxel)
5551 {
5552   FILE *fp;
5553   dsr *hdr;
5554 
5555   /* Open and read the header */
5556   fp = fopen(hdrfile,"r");
5557   if(fp == NULL){
5558     printf("ERROR: ReadAnalyzeHeader(): cannot open %s\n",hdrfile);
5559     return(NULL);
5560   }
5561 
5562   /* Read the header file */
5563   hdr = (dsr *) calloc(1, sizeof(dsr));
5564   fread(hdr, sizeof(dsr), 1, fp);
5565   fclose(fp);
5566 
5567   *swap = 0;
5568   if(hdr->hk.sizeof_hdr != sizeof(dsr))
5569     {
5570       *swap = 1;
5571       swap_analyze_header(hdr);
5572     }
5573 
5574   if(hdr->dime.datatype == DT_UNSIGNED_CHAR)
5575     {
5576       *mritype = MRI_UCHAR;
5577       *bytes_per_voxel = 1;
5578     }
5579   else if(hdr->dime.datatype == DT_SIGNED_SHORT)
5580     {
5581       *mritype = MRI_SHORT;
5582       *bytes_per_voxel = 2;
5583     }
5584   else if(hdr->dime.datatype == DT_SIGNED_INT)
5585     {
5586       *mritype = MRI_INT;
5587       *bytes_per_voxel = 4;
5588     }
5589   else if(hdr->dime.datatype == DT_FLOAT)
5590     {
5591       *mritype = MRI_FLOAT;
5592       *bytes_per_voxel = 4;
5593     }
5594   else if(hdr->dime.datatype == DT_DOUBLE)
5595     {
5596       *mritype = MRI_FLOAT;
5597       *bytes_per_voxel = 8;
5598     }
5599   else
5600     {
5601       free(hdr);
5602       errno = 0;
5603       ErrorReturn(NULL, (ERROR_UNSUPPORTED, "ReadAnalyzeHeader: "
5604                          "unsupported data type %d", hdr->dime.datatype));
5605     }
5606 
5607   return(hdr);
5608 }
5609 
5610 
5611 /*-------------------------------------------------------------------------
5612   analyzeRead() - see the end of file for the old (pre-10/11/01) analyzeRead().
5613   The fname can take one of several forms.
5614   -------------------------------------------------------------------------*/
5615 static MRI *analyzeRead(char *fname, int read_volume)
5616 {
5617   extern int N_Zero_Pad_Input;
5618   int nfiles, k, nread;
5619   char *stem;
5620   char imgfile[1000], hdrfile[1000], matfile[1000], fmt[1000];
5621   char *buf;
5622   FILE *fp;
5623   dsr *hdr;
5624   int swap, mritype, bytes_per_voxel, cantreadmatfile=0;
5625   int ncols, nrows, nslcs, nframes, row, slice, frame, startframe;
5626   MATRIX *T=NULL, *PcrsCenter, *PxyzCenter, *T1=NULL, *Q=NULL;
5627   MRI *mri;
5628   float min, max;
5629   struct stat StatBuf;
5630   int nv,nreal;
5631   char direction[64];
5632   int signX, signY, signZ;
5633 
5634   fp = NULL;
5635   startframe = GetSPMStartFrame();
5636 
5637   /* Count the number of files associated with this file name,
5638      and get the stem. */
5639   nfiles = CountAnalyzeFiles(fname,N_Zero_Pad_Input,&stem);
5640 
5641   /* If there are no files, return NULL */
5642   if(nfiles < 0) return(NULL);
5643   if(nfiles == 0){
5644     printf("ERROR: analyzeRead(): cannot find any files for %s\n",fname);
5645     return(NULL);
5646   }
5647   //printf("INFO: analyzeRead(): found %d files for %s\n",nfiles,fname);
5648 
5649   /* Create file names of header and mat files */
5650   if(N_Zero_Pad_Input > -1){
5651     sprintf(fmt,"%s%%0%dd.%%s",stem,N_Zero_Pad_Input);
5652     sprintf(hdrfile,fmt,startframe,"hdr");
5653     sprintf(matfile,fmt,startframe,"mat");
5654   }
5655   else{
5656     sprintf(hdrfile,"%s.hdr",stem);
5657     sprintf(matfile,"%s.mat",stem);
5658     sprintf(imgfile,"%s.img",stem);
5659   }
5660 
5661   hdr = ReadAnalyzeHeader(hdrfile, &swap, &mritype, &bytes_per_voxel);
5662   if(hdr == NULL) return(NULL);
5663   if (Gdiag & DIAG_VERBOSE_ON)  DumpAnalyzeHeader(stdout,hdr);
5664 
5665   /* Get the number of frames as either the fourth dimension or
5666      the number of files. */
5667   if(nfiles == 1){
5668     nframes = hdr->dime.dim[4];
5669     if(nframes==0) nframes = 1;
5670   }
5671   else  nframes = nfiles;
5672 
5673   ncols = hdr->dime.dim[1];
5674   nrows = hdr->dime.dim[2];
5675   nslcs = hdr->dime.dim[3];
5676   nv = ncols*nrows*nslcs*nframes;
5677 
5678   if( ncols == 1 || nrows == 1 ) {
5679     lstat(imgfile, &StatBuf);
5680     if(StatBuf.st_size != nv*bytes_per_voxel){
5681       nreal = StatBuf.st_size / bytes_per_voxel;
5682       if(ncols ==1) nrows = nreal;
5683       else          ncols = nreal;
5684       printf("INFO: %s really has %d rows/cols\n",imgfile,nreal);
5685     }
5686   }
5687 
5688   /* Alloc the Header and/or Volume */
5689   if(read_volume)
5690     mri = MRIallocSequence(ncols, nrows, nslcs, mritype, nframes);
5691   else {
5692     mri = MRIallocHeader(ncols, nrows, nslcs, mritype);
5693     mri->nframes = nframes;
5694   }
5695 
5696   /* Load Variables into header */
5697   mri->xsize = fabs(hdr->dime.pixdim[1]);  /* col res */
5698   mri->ysize = fabs(hdr->dime.pixdim[2]);  /* row res */
5699   mri->zsize = fabs(hdr->dime.pixdim[3]);  /* slice res */
5700   mri->tr    = 1000*hdr->dime.pixdim[4];  /* time  res */
5701 
5702   signX = (hdr->dime.pixdim[1] > 0) ? 1 : -1;
5703   signY = (hdr->dime.pixdim[2] > 0) ? 1 : -1;
5704   signZ = (hdr->dime.pixdim[3] > 0) ? 1 : -1;
5705 
5706   /* Read the matfile, if there */
5707   if(FileExists(matfile)){
5708     T1 = MatlabRead(matfile); // orientation info
5709     if(T1 == NULL){
5710       printf
5711         ("WARNING: analyzeRead(): matfile %s exists but could not read ... \n",
5712          matfile);
5713       printf("  may not be matlab4 mat file ... proceeding without it.\n");
5714       fflush(stdout);
5715       cantreadmatfile=1;
5716     }
5717     else{
5718       /* Convert from 1-based to 0-based */
5719       Q = MtxCRS1toCRS0(Q);
5720       T = MatrixMultiply(T1,Q,T);
5721       //printf("------- Analyze Input Matrix (zero-based) --------\n");
5722       //MatrixPrint(stdout,T);
5723       //printf("-------------------------------------\n");
5724       mri->ras_good_flag = 1;
5725       MatrixFree(&Q);
5726       MatrixFree(&T1);
5727     }
5728   }
5729   if(! FileExists(matfile) || cantreadmatfile){
5730     /* when not found, it is a fun exercise.                      */
5731     /* see http://wideman-one.com/gw/brain/analyze/formatdoc.htm  */
5732     /* for amgibuities.                                           */
5733     /* I will follow his advise                                   */
5734     /* hist.orient  Mayo name   Voxel[Index0, Index1, Index2] */
5735     /*                          Index0  Index1  Index2              */
5736     /* 0 transverse unflipped   R-L     P-A     I-S     LAS */
5737     /* 3 transverse flipped     R-L     A-P     I-S     LPS */
5738     /* 1 coronal unflipped      R-L     I-S     P-A     LSA */
5739     /* 4 coronal flipped        R-L     S-I     P-A     LIA */
5740     /* 2 sagittal unflipped     P-A     I-S     R-L     ASL */
5741     /* 5 sagittal flipped       P-A     S-I     R-L     AIL */
5742     //   P->A I->S L->R
5743 
5744     /* FLIRT distributes analyze format image which has a marked LR */
5745     /* in fls/etc/standard/avg152T1_LR-marked.img.  The convention    */
5746     /* is tested with this image for hdr->hist.orient== 0.              */
5747     /* note that flirt image has negative pixdim[1], but their software */
5748     /* ignores the sign anyway.                                         */
5749     if (hdr->hist.orient==0)  /* x = - r, y = a, z = s */
5750       {
5751         strcpy(direction, "transverse unflipped (default)");
5752         T = MatrixAlloc(4, 4, MATRIX_REAL);
5753         T->rptr[1][1] =  -mri->xsize;
5754         T->rptr[2][2] =  mri->ysize;
5755         T->rptr[3][3] =  mri->zsize;
5756         T->rptr[1][4] = mri->xsize*(mri->width/2.0);
5757         T->rptr[2][4] = -mri->ysize*(mri->height/2.0);
5758         T->rptr[3][4] = -mri->zsize*(mri->depth/2.0);
5759         T->rptr[4][4] = 1.;
5760       }
5761     else if (hdr->hist.orient==1) /* x = -r, y = s, z = a */
5762       {
5763         strcpy(direction, "coronal unflipped");
5764         T = MatrixAlloc(4, 4, MATRIX_REAL);
5765         T->rptr[1][1] = -mri->xsize;
5766         T->rptr[2][3] =  mri->zsize;
5767         T->rptr[3][2] =  mri->ysize;
5768         T->rptr[1][4] = mri->xsize*(mri->width/2.0);
5769         T->rptr[2][4] = -mri->zsize*(mri->depth/2.0);
5770         T->rptr[3][4] = -mri->ysize*(mri->height/2.0);
5771         T->rptr[4][4] = 1.;
5772       }
5773     else if (hdr->hist.orient==2) /* x = a, y = s, z = -r */
5774       {
5775         strcpy(direction, "sagittal unflipped");
5776         T = MatrixAlloc(4, 4, MATRIX_REAL);
5777         T->rptr[1][3] =  -mri->zsize;
5778         T->rptr[2][1] =  mri->xsize;
5779         T->rptr[3][2] =  mri->ysize;
5780         T->rptr[1][4] = mri->zsize*(mri->depth/2.0);
5781         T->rptr[2][4] = -mri->xsize*(mri->width/2.0);
5782         T->rptr[3][4] = -mri->ysize*(mri->height/2.0);
5783         T->rptr[4][4] = 1.;
5784       }
5785     else if (hdr->hist.orient==3) /* x = -r, y = -a, z = s */
5786       {
5787         strcpy(direction, "transverse flipped");
5788         T = MatrixAlloc(4, 4, MATRIX_REAL);
5789         T->rptr[1][1] =  -mri->xsize;
5790         T->rptr[2][2] =  -mri->ysize;
5791         T->rptr[3][3] =  mri->zsize;
5792         T->rptr[1][4] = mri->xsize*(mri->width/2.0);
5793         T->rptr[2][4] = mri->ysize*(mri->height/2.0);
5794         T->rptr[3][4] = -mri->zsize*(mri->depth/2.0);
5795         T->rptr[4][4] = 1.;
5796       }
5797     else if (hdr->hist.orient==4) /* x = -r, y = -s, z = a */
5798       {
5799         strcpy(direction, "coronal flipped");
5800         T = MatrixAlloc(4, 4, MATRIX_REAL);
5801         T->rptr[1][1] = -mri->xsize;
5802         T->rptr[2][3] =  mri->zsize;
5803         T->rptr[3][2] = -mri->ysize;
5804         T->rptr[1][4] =  mri->xsize*(mri->width/2.0);
5805         T->rptr[2][4] = -mri->zsize*(mri->depth/2.0);
5806         T->rptr[3][4] =  mri->ysize*(mri->height/2.0);
5807         T->rptr[4][4] = 1.;
5808       }
5809     else if (hdr->hist.orient==5) /* x = a, y = -s, z = -r */
5810       {
5811         strcpy(direction, "sagittal flipped");
5812         T = MatrixAlloc(4, 4, MATRIX_REAL);
5813         T->rptr[1][3] = -mri->zsize;
5814         T->rptr[2][1] =  mri->xsize;
5815         T->rptr[3][2] = -mri->ysize;
5816         T->rptr[1][4] =  mri->zsize*(mri->depth/2.0);
5817         T->rptr[2][4] = -mri->xsize*(mri->width/2.0);
5818         T->rptr[3][4] =  mri->ysize*(mri->height/2.0);
5819         T->rptr[4][4] = 1.;
5820       }
5821     if (hdr->hist.orient == -1){
5822       /* Unknown, so assume: x = -r, y = -a, z = s */
5823       strcpy(direction, "transverse flipped");
5824       T = MatrixAlloc(4, 4, MATRIX_REAL);
5825       T->rptr[1][1] = -mri->xsize;
5826       T->rptr[2][2] = -mri->ysize;
5827       T->rptr[3][3] =  mri->zsize;
5828       T->rptr[1][4] =  mri->xsize*(mri->width/2.0);
5829       T->rptr[2][4] =  mri->ysize*(mri->height/2.0);
5830       T->rptr[3][4] = -mri->zsize*(mri->depth/2.0);
5831       T->rptr[4][4] = 1.;
5832       mri->ras_good_flag = 0;
5833       fprintf(stderr,
5834               "WARNING: could not find %s file for direction cosine info.\n"
5835               "WARNING: Analyze 7.5 hdr->hist.orient value = -1, not valid.\n"
5836               "WARNING: assuming %s\n",matfile, direction);
5837     }
5838     else{
5839       mri->ras_good_flag = 1;
5840       fprintf
5841         (stderr,
5842          "-----------------------------------------------------------------\n"
5843          "INFO: could not find %s file for direction cosine info.\n"
5844          "INFO: use Analyze 7.5 hdr->hist.orient value: %d, %s.\n"
5845          "INFO: if not valid, please provide the information in %s file\n"
5846          "-----------------------------------------------------------------\n",
5847          matfile, hdr->hist.orient, direction, matfile
5848          );
5849     }
5850   }
5851 
5852   /* ---- Assign the Geometric Paramaters -----*/
5853   mri->x_r = T->rptr[1][1]/mri->xsize;
5854   mri->x_a = T->rptr[2][1]/mri->xsize;
5855   mri->x_s = T->rptr[3][1]/mri->xsize;
5856 
5857   /* Row Direction Cosines */
5858   mri->y_r = T->rptr[1][2]/mri->ysize;
5859   mri->y_a = T->rptr[2][2]/mri->ysize;
5860   mri->y_s = T->rptr[3][2]/mri->ysize;
5861 
5862   /* Slice Direction Cosines */
5863   mri->z_r = T->rptr[1][3]/mri->zsize;
5864   mri->z_a = T->rptr[2][3]/mri->zsize;
5865   mri->z_s = T->rptr[3][3]/mri->zsize;
5866 
5867   /* Center of the FOV in voxels */
5868   PcrsCenter = MatrixAlloc(4, 1, MATRIX_REAL);
5869   PcrsCenter->rptr[1][1] = mri->width/2.0;
5870   PcrsCenter->rptr[2][1] = mri->height/2.0;
5871   PcrsCenter->rptr[3][1] = mri->depth/2.0;
5872   PcrsCenter->rptr[4][1] = 1.0;
5873 
5874   /* Center of the FOV in XYZ */
5875   PxyzCenter = MatrixMultiply(T,PcrsCenter,NULL);
5876   mri->c_r = PxyzCenter->rptr[1][1];
5877   mri->c_a = PxyzCenter->rptr[2][1];
5878   mri->c_s = PxyzCenter->rptr[3][1];
5879 
5880   MatrixFree(&PcrsCenter);
5881   MatrixFree(&PxyzCenter);
5882   MatrixFree(&T);
5883 
5884   if(!read_volume) return(mri);
5885 
5886   /* Alloc the maximum amount of memory that a row could need */
5887   buf = (char *)malloc(mri->width * 8);
5888 
5889   /* Open the one file, if there is one file */
5890   if(nfiles == 1){
5891     fp = fopen(imgfile,"r");
5892     if(fp == NULL){
5893       printf("ERROR: analyzeRead(): could not open %s\n",imgfile);
5894       MRIfree(&mri);
5895       return(NULL);
5896     }
5897     fseek(fp, (int)(hdr->dime.vox_offset), SEEK_SET);
5898   }
5899 
5900   /*--------------------- Frame Loop --------------------------*/
5901   for(frame = 0; frame < nframes; frame++){
5902 
5903     /* Open the frame file if there is more than one file */
5904     if(N_Zero_Pad_Input > -1){
5905       sprintf(imgfile,fmt,frame+startframe,"img");
5906       fp = fopen(imgfile,"r");
5907       if(fp == NULL){
5908         printf("ERROR: analyzeRead(): could not open %s\n",imgfile);
5909         MRIfree(&mri);
5910         return(NULL);
5911       }
5912       fseek(fp, (int)(hdr->dime.vox_offset), SEEK_SET);
5913     }
5914 
5915     /* ----------- Slice Loop ----------------*/
5916     for(slice = 0;slice < mri->depth; slice++){
5917       k = slice + mri->depth * frame;
5918 
5919       /* --------- Row Loop ------------------*/
5920       for(row = 0; row < mri->height; row++)
5921         {
5922 
5923           nread = fread(buf, bytes_per_voxel, mri->width, fp);
5924           if(nread != mri->width){
5925             errno = 0;
5926             printf("frame = %d, slice = %d, k=%d, row = %d\n",
5927                    frame,slice,k,row);
5928             printf("nread = %d, nexpected = %d\n",nread,mri->width);
5929             fflush(stdout);
5930             MRIfree(&mri);free(buf);fclose(fp);
5931             ErrorReturn(NULL, (ERROR_BADFILE, "analyzeRead2(): error reading "
5932                                "from file %s\n", imgfile));
5933           }
5934 
5935           if(swap){
5936             if(bytes_per_voxel == 2)
5937               byteswapbufshort((void*)buf,bytes_per_voxel*mri->width);
5938             if(bytes_per_voxel == 4)
5939               byteswapbuffloat((void*)buf,bytes_per_voxel*mri->width);
5940             //nflip(buf, bytes_per_voxel, mri->width); /* byte swap */
5941           }
5942 
5943           memcpy
5944             (mri->slices[k][row], buf, bytes_per_voxel*mri->width); /*copy*/
5945 
5946         } /* End Row Loop */
5947     }  /* End Slice Loop */
5948 
5949     /* Close file if each frame is in a separate file */
5950     if(N_Zero_Pad_Input > -1) fclose(fp);
5951 
5952   }  /* End Frame Loop */
5953 
5954   if(N_Zero_Pad_Input < 0) fclose(fp);
5955 
5956   free(buf);
5957   free(hdr);
5958 
5959   MRIlimits(mri,&min,&max);
5960   printf("INFO: analyzeRead(): min = %g, max = %g\n",min,max);
5961 
5962   return(mri);
5963 }
5964 
5965 /*---------------------------------------------------------------
5966   analyzeWrite() - writes out a volume in SPM analyze format. If the
5967   file name has a .img extension, then the first frame is stored into
5968   the given file name. If it does not include the extension, then the
5969   volume is saved as a series of frame files using fname as a base
5970   followed by the zero-padded frame number (see analyzeWriteSeries).  A
5971   series can be saved from mri_convert by specifying the basename and
5972   adding "--out_type spm". See also analyzeWrite4D(). DNG
5973   ---------------------------------------------------------------*/
5974 static int analyzeWrite(MRI *mri, char *fname)
5975 {
5976   int len;
5977   int error_value;
5978 
5979   /* Check for .img extension */
5980   len = strlen(fname);
5981   if(len > 4){
5982     if(fname[len-4] == '.' && fname[len-3] == 'i' &&
5983        fname[len-2] == 'm' && fname[len-1] == 'g' ){
5984       /* There is a trailing .img - save frame 0 into fname */
5985       error_value = analyzeWriteFrame(mri, fname, 0);
5986       return(error_value);
5987     }
5988   }
5989   /* There is no trailing .img - save as a series */
5990   error_value = analyzeWriteSeries(mri, fname);
5991   return(error_value);
5992 }
5993 /*---------------------------------------------------------------
5994   analyzeWriteFrame() - this used to be analyzeWrite() but was modified
5995   by DNG to be able to save a particular frame so that it could be
5996   used to write out an entire series.
5997   ---------------------------------------------------------------*/
5998 static void printDirCos(MRI *mri)
5999 {
6000   fprintf(stderr, "Direction cosines for %s are:\n", mri->fname);
6001   fprintf(stderr, "  x_r = %8.4f, y_r = %8.4f, z_r = %8.4f, c_r = %10.4f\n",
6002           mri->x_r, mri->y_r, mri->z_r, mri->c_r);
6003   fprintf(stderr, "  x_a = %8.4f, y_a = %8.4f, z_a = %8.4f, c_a = %10.4f\n",
6004           mri->x_a, mri->y_a, mri->z_a, mri->c_a);
6005   fprintf(stderr, "  x_s = %8.4f, y_s = %8.4f, z_s = %8.4f, c_s = %10.4f\n",
6006           mri->x_s, mri->y_s, mri->z_s, mri->c_s);
6007 }
6008 
6009 static int analyzeWriteFrame(MRI *mri, char *fname, int frame)
6010 {
6011   dsr hdr;
6012   float max, min, det;
6013   MATRIX *T, *invT;
6014   char hdr_fname[STRLEN];
6015   char mat_fname[STRLEN];
6016   char *c;
6017   FILE *fp;
6018   int error_value;
6019   int i, j, k;
6020   int bytes_per_voxel;
6021   short i1, i2, i3;
6022   int shortmax;
6023   char *orientname[7] =
6024     { "transverse unflipped", "coronal unflipped", "sagittal unflipped",
6025       "transverse flipped", "coronal flipped", "sagittal flipped",
6026       "unknown" };
6027 
6028   if(frame >= mri->nframes){
6029     fprintf(stderr,"ERROR: analyzeWriteFrame(): frame number (%d) exceeds "
6030             "number of frames (%d)\n",frame,mri->nframes);
6031     return(1);
6032   }
6033 
6034   shortmax = (int)(pow(2.0,15.0));
6035   if(mri->width > shortmax){
6036     printf("ANALYZE FORMAT ERROR: ncols %d in volume exceeds %d\n",
6037            mri->width,shortmax);
6038     exit(1);
6039   }
6040   if(mri->height > shortmax){
6041     printf("ANALYZE FORMAT ERROR: nrows %d in volume exceeds %d\n",
6042            mri->height,shortmax);
6043     exit(1);
6044   }
6045   if(mri->depth > shortmax){
6046     printf("ANALYZE FORMAT ERROR: nslices %d in volume exceeds %d\n",
6047            mri->depth,shortmax);
6048     exit(1);
6049   }
6050   if(mri->nframes > shortmax){
6051     printf("ANALYZE FORMAT ERROR:  nframes %d in volume exceeds %d\n",
6052            mri->nframes,shortmax);
6053     exit(1);
6054   }
6055 
6056   c = strrchr(fname, '.');
6057   if(c == NULL)
6058     {
6059       errno = 0;
6060       ErrorReturn(ERROR_BADPARM, (ERROR_BADPARM, "analyzeWriteFrame(): "
6061                                   "bad file name %s", fname));
6062     }
6063   if(strcmp(c, ".img") != 0)
6064     {
6065       errno = 0;
6066       ErrorReturn(ERROR_BADPARM, (ERROR_BADPARM, "analyzeWriteFrame(): "
6067                                   "bad file name %s", fname));
6068     }
6069 
6070   strcpy(hdr_fname, fname);
6071   sprintf(hdr_fname + (c - fname), ".hdr");
6072 
6073   strcpy(mat_fname, fname);
6074   sprintf(mat_fname + (c - fname), ".mat");
6075 
6076   memset(&hdr, 0x00, sizeof(hdr));
6077 
6078   hdr.hk.sizeof_hdr = sizeof(hdr);
6079 
6080   hdr.dime.vox_offset = 0.0;
6081 
6082   if(mri->type == MRI_UCHAR)
6083     {
6084       hdr.dime.datatype = DT_UNSIGNED_CHAR;
6085       bytes_per_voxel = 1;
6086     }
6087   else if(mri->type == MRI_SHORT)
6088     {
6089       hdr.dime.datatype = DT_SIGNED_SHORT;
6090       bytes_per_voxel = 2;
6091     }
6092   /* --- assuming long and int are identical --- */
6093   else if(mri->type == MRI_INT || mri->type == MRI_LONG)
6094     {
6095       hdr.dime.datatype = DT_SIGNED_INT;
6096       bytes_per_voxel = 4;
6097     }
6098   else if(mri->type == MRI_FLOAT)
6099     {
6100       hdr.dime.datatype = DT_FLOAT;
6101       bytes_per_voxel = 4;
6102     }
6103   else
6104     {
6105       errno = 0;
6106       ErrorReturn
6107         (ERROR_BADPARM,
6108          (ERROR_BADPARM,
6109           "analyzeWriteFrame(): bad data type %d", mri->type));
6110     }
6111 
6112   /* Added by DNG 10/2/01 */
6113   hdr.dime.dim[0] = 4; /* number of dimensions */
6114   hdr.dime.dim[4] = 1; /* time */
6115   hdr.dime.pixdim[4] = mri->tr/1000.0; // convert to sec
6116   hdr.dime.bitpix = 8*bytes_per_voxel;
6117   memcpy(hdr.dime.vox_units,"mm\0",3);
6118   /*----------------------------*/
6119 
6120   hdr.dime.dim[1] = mri->width;    /* ncols */
6121   hdr.dime.dim[2] = mri->height;   /* nrows */
6122   hdr.dime.dim[3] = mri->depth;    /* nslices */
6123 
6124   hdr.dime.pixdim[1] = mri->xsize; /* col res */
6125   hdr.dime.pixdim[2] = mri->ysize; /* row res */
6126   hdr.dime.pixdim[3] = mri->zsize; /* slice res */
6127 
6128   MRIlimits(mri, &min, &max);
6129   hdr.dime.glmin = (int)min;
6130   hdr.dime.glmax = (int)max;
6131 
6132   /* Construct the matrix to convert CRS to XYZ, assuming
6133      that CRS is 1-based */
6134   T = MRIxfmCRS2XYZ(mri,1);
6135 
6136   det = MatrixDeterminant(T) ;
6137   if(det == 0){
6138     printf("WARNING: cannot determine volume orientation, "
6139            "assuming identity. It's ok if the output is a surface.\n");
6140     T = MatrixIdentity(4, T) ;
6141     if(mri->xsize > 0) T->rptr[1][1] = mri->xsize;
6142     if(mri->ysize > 0) T->rptr[2][2] = mri->ysize;
6143     if(mri->zsize > 0) T->rptr[3][3] = mri->zsize;
6144   }
6145   if(frame == 0){
6146     printf("Analyze Output Matrix\n");
6147     MatrixPrint(stdout,T);
6148     printf("--------------------\n");
6149   }
6150 
6151   /* ----- write the matrix to the .mat file ----- */
6152   error_value = MatlabWrite(T, mat_fname, "M");
6153   if(error_value != NO_ERROR) return(error_value);
6154 
6155   /* Compute inverse ot T (converts from XYZ to CRS) */
6156   invT = MatrixInverse(T,NULL);
6157   /* If the inverse cannot be computed, set to the identity */
6158   if(invT == NULL) invT = MatrixIdentity(4,NULL);
6159 
6160   /* Load the CRS into the originator field as 3 shorts for SPM */
6161   /* These come from the last column of invT */
6162   i1 = (short)(rint(*MATRIX_RELT(invT, 1, 4)));
6163   memcpy( (&hdr.hist.originator[0]), &i1, sizeof(short));
6164   i2 = (short)(rint(*MATRIX_RELT(invT, 2, 4)));
6165   memcpy( (&hdr.hist.originator[0] + sizeof(short)), &i2, sizeof(short));
6166   i3 = (short)(rint(*MATRIX_RELT(invT, 3, 4)));
6167   memcpy( (&hdr.hist.originator[0] + 2*sizeof(short)), &i3, sizeof(short));
6168 
6169   MatrixFree(&T);
6170   MatrixFree(&invT);
6171 
6172   /* Set the hist.orient field -- this is not always correct */
6173   /* see http://wideman-one.com/gw/brain/analyze/formatdoc.htm  */
6174   if(fabs(mri->z_s) > fabs(mri->z_r) && fabs(mri->z_s) > fabs(mri->z_a))
6175     {
6176       // Transverse: Superior/Inferior > both Right and Anterior
6177       if (mri->x_r < 0 && mri->y_a > 0 && mri->z_s > 0)
6178         hdr.hist.orient = 0; // transverse unflipped  LAS
6179       else if (mri->x_r < 0 && mri->y_a <0 && mri->z_s > 0)
6180         hdr.hist.orient = 3; // transverse flipped    LPS
6181       else
6182         {
6183           fprintf
6184             (stderr,
6185              "No such orientation specified in Analyze7.5. "
6186              "Set orient to 0.\n");
6187           fprintf(stderr, "Not a problem as long as you use the .mat file.\n");
6188           printDirCos(mri);
6189           hdr.hist.orient = 0;
6190         }
6191     }
6192   if(fabs(mri->z_a) > fabs(mri->z_r) && fabs(mri->z_a) > fabs(mri->z_s))
6193     {
6194       // Cor: Anterior/Post > both Right and Superior
6195       if(mri->x_r < 0 && mri->y_s > 0 && mri->z_a > 0)
6196         hdr.hist.orient = 1; // cor unflipped   LSA
6197       else if (mri->x_r <0 && mri->y_s < 0 && mri->z_a > 0)
6198         hdr.hist.orient = 4; // cor flipped     LIA
6199       else
6200         {
6201           fprintf(stderr,
6202                   "No such orientation specified in Analyze7.5. "
6203                   "Set orient to 0\n");
6204           printDirCos(mri);
6205           hdr.hist.orient = 0;
6206         }
6207     }
6208   if(fabs(mri->z_r) > fabs(mri->z_a) && fabs(mri->z_r) > fabs(mri->z_s))
6209     {
6210       // Sag: Righ/Left > both Anterior and Superior
6211       if(mri->x_a > 0 && mri->y_s > 0 && mri->z_r < 0)
6212         hdr.hist.orient = 2; // sag unflipped   ASL
6213       else if (mri->x_a > 0 && mri->y_s < 0 && mri->z_r < 0)
6214         hdr.hist.orient = 5; // sag flipped     AIL
6215       else
6216         {
6217           fprintf
6218             (stderr,
6219              "No such orientation specified in Analyze7.5. Set orient to 0\n");
6220           printDirCos(mri);
6221           hdr.hist.orient = 0;
6222         }
6223     }
6224   printf("INFO: set hdr.hist.orient to '%s'\n",
6225          orientname[(int) hdr.hist.orient]);
6226 
6227   /* ----- open the header file ----- */
6228   if((fp = fopen(hdr_fname, "w")) == NULL){
6229     errno = 0;
6230     ErrorReturn
6231       (ERROR_BADFILE,
6232        (ERROR_BADFILE,
6233         "analyzeWriteFrame(): error opening file %s for writing",
6234         hdr_fname));
6235   }
6236   /* ----- write the header ----- */
6237   /* should write element-by-element */
6238   if(fwrite(&hdr, sizeof(hdr), 1, fp) != 1){
6239     errno = 0;
6240     ErrorReturn
6241       (ERROR_BADFILE,
6242        (ERROR_BADFILE,
6243         "analyzeWriteFrame(): error writing to file %s", hdr_fname));
6244   }
6245   fclose(fp);
6246 
6247   /* ----- open the data file ----- */
6248   if((fp = fopen(fname, "w")) == NULL){
6249     errno = 0;
6250     ErrorReturn
6251       (ERROR_BADFILE,
6252        (ERROR_BADFILE,
6253         "analyzeWriteFrame(): error opening file %s for writing", fname));
6254   }
6255 
6256   /* ----- write the data ----- */
6257   for(i = 0;i < mri->depth;i++){
6258     /* this is the change to make it save a given frame */
6259     k = i + mri->depth*frame;
6260     for(j = 0;j < mri->height;j++){
6261       if(fwrite(mri->slices[k][j], bytes_per_voxel, mri->width, fp) !=
6262          mri->width)
6263         {
6264           errno = 0;
6265           ErrorReturn(ERROR_BADFILE, (ERROR_BADFILE, "analyzeWriteFrame(): "
6266                                       " error writing to file %s",
6267                                       fname));
6268         } /* end if */
6269     } /* end row loop */
6270   } /* end col loop */
6271 
6272   fclose(fp);
6273 
6274   return(0);
6275 
6276 } /* end analyzeWriteFrame() */
6277 
6278 /*-------------------------------------------------------------*/
6279 static int analyzeWriteSeries(MRI *mri, char *fname)
6280 {
6281   extern int N_Zero_Pad_Output;
6282   int frame;
6283   int err;
6284   char framename[STRLEN];
6285   char spmnamefmt[STRLEN];
6286 
6287   /* NOTE: This function assumes that fname does not have a .img extension. */
6288 
6289   /* N_Zero_Pad_Output is a global variable used to control the name of      */
6290   /* files in successive frames within the series. It can be set from     */
6291   /* mri_convert using "--spmnzeropad N" where N is the width of the pad. */
6292   if(N_Zero_Pad_Output < 0) N_Zero_Pad_Output = 3;
6293 
6294   /* Create the format string used to create the filename for each frame.   */
6295   /* The frame file name format will be fname%0Nd.img where N is the amount */
6296   /* of zero padding. The (padded) frame numbers will go from 1 to nframes. */
6297   sprintf(spmnamefmt,"%%s%%0%dd.img",N_Zero_Pad_Output);
6298 
6299   /* loop over slices */
6300   for(frame = 0; frame < mri->nframes; frame ++){
6301     sprintf(framename,spmnamefmt,fname,frame+1);
6302     //printf("%3d %s\n",frame,framename);
6303     err = analyzeWriteFrame(mri, framename, frame);
6304     if(err) return(err);
6305   }
6306 
6307   return(0);
6308 }
6309 
6310 /*---------------------------------------------------------------
6311   analyzeWrite4D() - saves data in analyze 4D format.
6312   ---------------------------------------------------------------*/
6313 static int analyzeWrite4D(MRI *mri, char *fname)
6314 {
6315   dsr hdr;
6316   float max, min, det;
6317   MATRIX *T, *invT;
6318   char hdr_fname[STRLEN];
6319   char mat_fname[STRLEN];
6320   char *c;
6321   FILE *fp;
6322   int error_value;
6323   int i, j, k, frame;
6324   int bytes_per_voxel;
6325   short i1, i2, i3;
6326   int shortmax;
6327 
6328   c = strrchr(fname, '.');
6329   if(c == NULL)
6330     {
6331       errno = 0;
6332       ErrorReturn(ERROR_BADPARM, (ERROR_BADPARM, "analyzeWrite4D(): "
6333                                   "bad file name %s", fname));
6334     }
6335   if(strcmp(c, ".img") != 0)
6336     {
6337       errno = 0;
6338       ErrorReturn(ERROR_BADPARM, (ERROR_BADPARM, "analyzeWrite4D(): "
6339                                   "bad file name %s", fname));
6340     }
6341 
6342   shortmax = (int)(pow(2.0,15.0));
6343   if(mri->width > shortmax)
6344     printf("ANALYZE FORMAT WARNING: ncols %d in volume exceeds %d\n",
6345            mri->width,shortmax);
6346   if(mri->height > shortmax)
6347     printf("ANALYZE FORMAT WARNING: nrows %d in volume exceeds %d\n",
6348            mri->height,shortmax);
6349   if(mri->depth > shortmax)
6350     printf("ANALYZE FORMAT WARNING: nslices %d in volume exceeds %d\n",
6351            mri->depth,shortmax);
6352   if(mri->nframes > shortmax)
6353     printf("ANALYZE FORMAT WARNING:  nframes %d in volume exceeds %d\n",
6354            mri->nframes,shortmax);
6355 
6356   /* create the file name for the header */
6357   strcpy(hdr_fname, fname);
6358   sprintf(hdr_fname + (c - fname), ".hdr");
6359 
6360   /* create the file name for the mat file */
6361   strcpy(mat_fname, fname);
6362   sprintf(mat_fname + (c - fname), ".mat");
6363 
6364   memset(&hdr, 0x00, sizeof(hdr));
6365   hdr.hk.sizeof_hdr = sizeof(hdr);
6366 
6367   hdr.dime.vox_offset = 0.0;
6368 
6369   if(mri->type == MRI_UCHAR)
6370     {
6371       hdr.dime.datatype = DT_UNSIGNED_CHAR;
6372       bytes_per_voxel = 1;
6373     }
6374   else if(mri->type == MRI_SHORT)
6375     {
6376       hdr.dime.datatype = DT_SIGNED_SHORT;
6377       bytes_per_voxel = 2;
6378     }
6379   /* --- assuming long and int are identical --- */
6380   else if(mri->type == MRI_INT || mri->type == MRI_LONG)
6381     {
6382       hdr.dime.datatype = DT_SIGNED_INT;
6383       bytes_per_voxel = 4;
6384     }
6385   else if(mri->type == MRI_FLOAT)
6386     {
6387       hdr.dime.datatype = DT_FLOAT;
6388       bytes_per_voxel = 4;
6389     }
6390   else
6391     {
6392       errno = 0;
6393       ErrorReturn
6394         (ERROR_BADPARM,
6395          (ERROR_BADPARM,
6396           "analyzeWrite4D(): bad data type %d", mri->type));
6397     }
6398 
6399   hdr.dime.bitpix = 8*bytes_per_voxel;
6400   memcpy(hdr.dime.vox_units,"mm\0",3);
6401 
6402   hdr.dime.dim[1] = mri->width;    /* ncols */
6403   hdr.dime.dim[2] = mri->height;   /* nrows */
6404   hdr.dime.dim[3] = mri->depth;    /* nslices */
6405   hdr.dime.dim[4] = mri->nframes;
6406   hdr.dime.dim[0] = 4;              /* flirt expects to be always 4 */
6407 
6408   hdr.dime.pixdim[1] = mri->xsize; /* col res */
6409   hdr.dime.pixdim[2] = mri->ysize; /* row res */
6410   hdr.dime.pixdim[3] = mri->zsize; /* slice res */
6411   hdr.dime.pixdim[4] = mri->tr/1000.0; /* time res in sec*/
6412 
6413   MRIlimits(mri, &min, &max);
6414   hdr.dime.glmin = (int)min;
6415   hdr.dime.glmax = (int)max;
6416 
6417   /* Construct the matrix to convert CRS to XYZ, assuming
6418      that CRS is 1-based */
6419   T = MRIxfmCRS2XYZ(mri,1);
6420 
6421   det = MatrixDeterminant(T) ;
6422   if(det == 0){
6423     printf("WARNING: cannot determine volume orientation, "
6424            "assuming identity. It's ok if the output is a surface.\n");
6425     T = MatrixIdentity(4, T) ;
6426     if(mri->xsize > 0) T->rptr[1][1] = mri->xsize;
6427     if(mri->ysize > 0) T->rptr[2][2] = mri->ysize;
6428     if(mri->zsize > 0) T->rptr[3][3] = mri->zsize;
6429   }
6430   printf("Analyze Output Matrix\n");
6431   MatrixPrint(stdout,T);
6432   printf("--------------------\n");
6433 
6434 
6435   /* Set the hist.orient field -- this is not always correct */
6436   /* see http://wideman-one.com/gw/brain/analyze/formatdoc.htm  */
6437   if(fabs(mri->z_s) > fabs(mri->z_r) && fabs(mri->z_s) > fabs(mri->z_a)){
6438     // Transverse: Superior/Inferior > both Right and Anterior
6439     if(mri->x_r > 0) hdr.hist.orient = 0; // transverse unflipped
6440     else             hdr.hist.orient = 3; // transverse flipped
6441   }
6442   if(fabs(mri->z_a) > fabs(mri->z_r) && fabs(mri->z_a) > fabs(mri->z_s)){
6443     // Cor: Anterior/Post > both Right and Superior
6444     if(mri->x_r > 0) hdr.hist.orient = 1; // cor unflipped
6445     else             hdr.hist.orient = 4; // cor flipped
6446   }
6447   if(fabs(mri->z_r) > fabs(mri->z_a) && fabs(mri->z_r) > fabs(mri->z_s)){
6448     // Sag: Righ/Left > both Anterior and Superior
6449     if(mri->x_r > 0) hdr.hist.orient = 2; // sag unflipped
6450     else             hdr.hist.orient = 5; // sag flipped
6451   }
6452   hdr.hist.orient = -1;
6453   printf("INFO: set hdr.hist.orient to %d\n",hdr.hist.orient);
6454 
6455   /* ----- write T to the  .mat file ----- */
6456   error_value = MatlabWrite(T, mat_fname, "M");
6457   if(error_value != NO_ERROR) return(error_value);
6458 
6459   /* This matrix converts from XYZ to CRS */
6460   invT = MatrixInverse(T,NULL);
6461   /* If the inverse cannot be computed, set to the identity */
6462   if(invT == NULL) invT = MatrixIdentity(4,NULL);
6463 
6464   /* Load the CRS into the originator field as 3 shorts for SPM */
6465   /* These come from the last column of invT */
6466   i1 = (short)(rint(*MATRIX_RELT(invT, 1, 4)));
6467   memcpy( (&hdr.hist.originator[0]), &i1, sizeof(short));
6468   i2 = (short)(rint(*MATRIX_RELT(invT, 2, 4)));
6469   memcpy( (&hdr.hist.originator[0] + sizeof(short)), &i2, sizeof(short));
6470   i3 = (short)(rint(*MATRIX_RELT(invT, 3, 4)));
6471   memcpy( (&hdr.hist.originator[0] + 2*sizeof(short)), &i3, sizeof(short));
6472 
6473   MatrixFree(&T);
6474   MatrixFree(&invT);
6475 
6476   /* ----- write the header ----- */
6477   if((fp = fopen(hdr_fname, "w")) == NULL)
6478     {
6479       errno = 0;
6480       ErrorReturn
6481         (ERROR_BADFILE,
6482          (ERROR_BADFILE,
6483           "analyzeWrite4D(): error opening file %s for writing",
6484           hdr_fname));
6485     }
6486   if(fwrite(&hdr, sizeof(hdr), 1, fp) != 1)
6487     {
6488       errno = 0;
6489       ErrorReturn
6490         (ERROR_BADFILE,
6491          (ERROR_BADFILE,
6492           "analyzeWrite4D(): error writing to file %s",
6493           hdr_fname));
6494     }
6495   fclose(fp);
6496 
6497   /* ----- write the data ----- */
6498   if((fp = fopen(fname, "w")) == NULL)
6499     {
6500       errno = 0;
6501       ErrorReturn
6502         (ERROR_BADFILE,
6503          (ERROR_BADFILE,
6504           "analyzeWrite4D(): error opening file %s for writing",
6505           fname));
6506     }
6507 
6508   for(frame = 0; frame < mri->nframes; frame ++){
6509     for(i = 0;i < mri->depth;i++){
6510       k = i + mri->depth*frame;
6511       for(j = 0;j < mri->height;j++){
6512         if(fwrite(mri->slices[k][j], bytes_per_voxel, mri->width, fp) !=
6513            mri->width){
6514           errno = 0;
6515           ErrorReturn(ERROR_BADFILE, (ERROR_BADFILE, "analyzeWrite4D(): "
6516                                       "error writing to file %s", fname));
6517         }
6518       }
6519     }
6520   }
6521 
6522   fclose(fp);
6523 
6524   return(0);
6525 
6526 } /* end analyzeWrite4D() */
6527 
6528 /*-------------------------------------------------------------*/
6529 static void swap_analyze_header(dsr *hdr)
6530 {
6531 
6532   int i;
6533   char c;
6534 
6535   hdr->hk.sizeof_hdr = swapInt(hdr->hk.sizeof_hdr);
6536   hdr->hk.extents = swapShort(hdr->hk.extents);
6537   hdr->hk.session_error = swapShort(hdr->hk.session_error);
6538 
6539   for(i = 0;i < 5;i++)
6540     hdr->dime.dim[i] = swapShort(hdr->dime.dim[i]);
6541   hdr->dime.unused1 = swapShort(hdr->dime.unused1);
6542   hdr->dime.datatype = swapShort(hdr->dime.datatype);
6543   hdr->dime.bitpix = swapShort(hdr->dime.bitpix);
6544   hdr->dime.dim_un0 = swapShort(hdr->dime.dim_un0);
6545   hdr->dime.vox_offset = swapFloat(hdr->dime.vox_offset);
6546   hdr->dime.roi_scale = swapFloat(hdr->dime.roi_scale);
6547   hdr->dime.funused1 = swapFloat(hdr->dime.funused1);
6548   hdr->dime.funused2 = swapFloat(hdr->dime.funused2);
6549   hdr->dime.cal_max = swapFloat(hdr->dime.cal_max);
6550   hdr->dime.cal_min = swapFloat(hdr->dime.cal_min);
6551   hdr->dime.compressed = swapInt(hdr->dime.compressed);
6552   hdr->dime.verified = swapInt(hdr->dime.verified);
6553   hdr->dime.glmin = swapInt(hdr->dime.glmin);
6554   hdr->dime.glmax = swapInt(hdr->dime.glmax);
6555   for(i = 0;i < 8;i++)
6556     hdr->dime.pixdim[i] = swapFloat(hdr->dime.pixdim[i]);
6557 
6558   hdr->hist.views = swapInt(hdr->hist.views);
6559   hdr->hist.vols_added = swapInt(hdr->hist.vols_added);
6560   hdr->hist.start_field = swapInt(hdr->hist.start_field);
6561   hdr->hist.field_skip = swapInt(hdr->hist.field_skip);
6562   hdr->hist.omax = swapInt(hdr->hist.omax);
6563   hdr->hist.omin = swapInt(hdr->hist.omin);
6564   hdr->hist.smax = swapInt(hdr->hist.smax);
6565   hdr->hist.smin = swapInt(hdr->hist.smin);
6566 
6567   /* spm uses the originator char[10] as shorts */
6568   for(i = 0;i < 5;i++)
6569     {
6570       c = hdr->hist.originator[2*i+1];
6571       hdr->hist.originator[2*i+1] = hdr->hist.originator[2*i];
6572       hdr->hist.originator[2*i] = c;
6573     }
6574 
6575 } /* end swap_analyze_header */
6576 /*------------------------------------------------------*/
6577 
6578 #if 0
6579 static int bad_ras_fill(MRI *mri)
6580 {
6581   if(mri->slice_direction == MRI_CORONAL)
6582     {
6583       mri->x_r = -1.0;  mri->y_r =  0.0;  mri->z_r =  0.0;
6584       mri->x_a =  0.0;  mri->y_a =  0.0;  mri->z_a =  1.0;
6585       mri->x_s =  0.0;  mri->y_s = -1.0;  mri->z_s =  0.0;
6586       mri->c_r = 0.0;  mri->c_a = 0.0;  mri->c_s = 0.0;
6587     }
6588   else if(mri->slice_direction == MRI_SAGITTAL)
6589     {
6590       mri->x_r =  0.0;  mri->y_r =  0.0;  mri->z_r = -1.0;
6591       mri->x_a =  1.0;  mri->y_a =  0.0;  mri->z_a =  0.0;
6592       mri->x_s =  0.0;  mri->y_s =  1.0;  mri->z_s =  0.0;
6593       mri->c_r = 0.0;  mri->c_a = 0.0;  mri->c_s = 0.0;
6594     }
6595   else if(mri->slice_direction == MRI_HORIZONTAL)
6596     {
6597       mri->x_r =  1.0;  mri->y_r =  0.0;  mri->z_r =  0.0;
6598       mri->x_a =  0.0;  mri->y_a = -1.0;  mri->z_a =  0.0;
6599       mri->x_s =  0.0;  mri->y_s =  0.0;  mri->z_s =  1.0;
6600       mri->c_r = 0.0;  mri->c_a = 0.0;  mri->c_s = 0.0;
6601     }
6602   else
6603     {
6604       errno = 0;
6605       ErrorReturn
6606         (ERROR_BADPARM,
6607          (ERROR_BADPARM, "bad_ras_fill(): unknown slice direction"));
6608     }
6609 
6610   return(NO_ERROR);
6611 
6612 } /* end bad_ras_fill() */
6613 #endif
6614 
6615 #if 0
6616 // #ifdef VT_TO_CV
6617 
6618 static int voxel_center_to_center_voxel(MRI *mri, float *x, float *y, float *z)
6619 {
6620 
6621   int result;
6622   MATRIX *m, *i, *r, *mi;
6623 
6624   if(!mri->ras_good_flag)
6625     if((result = bad_ras_fill(mri)) != NO_ERROR)
6626       return(result);
6627 
6628   if((m = extract_i_to_r(mri)) == NULL)
6629     return(ERROR_BADPARM);
6630 
6631   mi = MatrixInverse(m, NULL);
6632   if(mi == NULL)
6633     {
6634       MatrixFree(&m);
6635       errno = 0;
6636       ErrorReturn
6637         (ERROR_BADPARM,
6638          (ERROR_BADPARM,
6639           "voxel_center_to_center_voxel(): error inverting matrix"));
6640     }
6641 
6642   r = MatrixAlloc(4, 1, MATRIX_REAL);
6643   if(r == NULL)
6644     {
6645       MatrixFree(&m);
6646       MatrixFree(&mi);
6647       errno = 0;
6648       ErrorReturn
6649         (ERROR_NOMEMORY,
6650          (ERROR_NOMEMORY,
6651           "voxel_center_to_center_voxel(): couldn't allocate matrix"));
6652     }
6653 
6654   *MATRIX_RELT(r, 1, 1) = 0.0;
6655   *MATRIX_RELT(r, 2, 1) = 0.0;
6656   *MATRIX_RELT(r, 3, 1) = 0.0;
6657   *MATRIX_RELT(r, 4, 1) = 1.0;
6658 
6659   i = MatrixMultiply(mi, r, NULL);
6660   if(i == NULL)
6661     {
6662       MatrixFree(&m);
6663       MatrixFree(&mi);
6664       MatrixFree(&r);
6665       errno = 0;
6666       ErrorReturn
6667         (ERROR_BADPARM,
6668          (ERROR_BADPARM,
6669           "voxel_center_to_center_voxel(): "
6670           "error in matrix multiplication"));
6671     }
6672 
6673   *x = *MATRIX_RELT(i, 1, 1);
6674   *y = *MATRIX_RELT(i, 2, 1);
6675   *z = *MATRIX_RELT(i, 3, 1);
6676 
6677   MatrixFree(&m);
6678   MatrixFree(&mi);
6679   MatrixFree(&i);
6680   MatrixFree(&r);
6681 
6682   return(NO_ERROR);
6683 
6684 } /* end voxel_center_to_center_voxel() */
6685 
6686 // #endif
6687 
6688 static int center_voxel_to_voxel_center(MRI *mri, float x, float y, float z)
6689 {
6690 
6691   int result;
6692   MATRIX *m;
6693 
6694   if(!mri->ras_good_flag)
6695     if((result = bad_ras_fill(mri)) != NO_ERROR)
6696       return(result);
6697 
6698   if((m = extract_i_to_r(mri)) == NULL)
6699     return(ERROR_BADPARM);
6700 
6701   *MATRIX_RELT(m, 1, 4) =
6702     0 - (*MATRIX_RELT(m, 1, 1) * x +
6703          *MATRIX_RELT(m, 1, 2) * y +
6704          *MATRIX_RELT(m, 1, 3) * z);
6705   *MATRIX_RELT(m, 2, 4) =
6706     0 - (*MATRIX_RELT(m, 2, 1) * x +
6707          *MATRIX_RELT(m, 2, 2) * y +
6708          *MATRIX_RELT(m, 2, 3) * z);
6709   *MATRIX_RELT(m, 3, 4) =
6710     0 - (*MATRIX_RELT(m, 3, 1) * x +
6711          *MATRIX_RELT(m, 3, 2) * y +
6712          *MATRIX_RELT(m, 3, 3) * z);
6713 
6714   apply_i_to_r(mri, m);
6715 
6716   MatrixFree(&m);
6717 
6718   return(NO_ERROR);
6719 
6720 } /* end center_voxel_to_voxel_center() */
6721 #endif // if 0
6722 
6723 static MRI *gdfRead(char *fname, int read_volume)
6724 {
6725 
6726   MRI *mri;
6727   FILE *fp;
6728   char line[STRLEN];
6729   char *c;
6730   char file_path[STRLEN];
6731   float ipr[2];
6732   float st;
6733   char units_string[STRLEN], orientation_string[STRLEN],
6734     data_type_string[STRLEN];
6735   int size[2];
6736   int path_d, ipr_d, st_d, u_d, dt_d, o_d, s_d,
6737     x_ras_d, y_ras_d, z_ras_d, c_ras_d;
6738   int data_type;
6739   int orientation = MRI_UNDEFINED;
6740   char *or;
6741   char os_orig[STRLEN];
6742   float units_factor;
6743   char file_path_1[STRLEN], file_path_2[STRLEN];
6744   int i, j, k;
6745   short *sbuf = NULL;
6746   float *fbuf = NULL;
6747   unsigned char *ucbuf = NULL;
6748   int n_files;
6749   char fname_use[STRLEN];
6750   int pad_zeros_flag;
6751   int file_offset = 0;
6752   float x_r, x_a, x_s;
6753   float y_r, y_a, y_s;
6754   float z_r, z_a, z_s;
6755   float c_r, c_a, c_s;
6756 
6757   if((fp = fopen(fname, "r")) == NULL)
6758     {
6759       errno = 0;
6760       ErrorReturn
6761         (NULL,
6762          (ERROR_BADFILE, "gdfRead(): error opening file %s", fname));
6763     }
6764 
6765   /* --- defined flags --- */
6766   path_d = ipr_d = st_d = u_d = dt_d =
6767     o_d = s_d = x_ras_d = y_ras_d = z_ras_d = c_ras_d = FALSE;
6768 
6769   while(fgets(line, STRLEN, fp) != NULL)
6770     {
6771 
6772       /* --- strip the newline --- */
6773       if((c = strrchr(line, '\n')) != NULL)
6774         *c = '\0';
6775 
6776       if(strncmp(line, "IMAGE_FILE_PATH", 15) == 0)
6777         {
6778           sscanf(line, "%*s %s", file_path);
6779           path_d = TRUE;
6780         }
6781       else if(strncmp(line, "IP_RES", 6) == 0)
6782         {
6783           sscanf(line, "%*s %f %f", &ipr[0], &ipr[1]);
6784           ipr_d = TRUE;
6785         }
6786       else if(strncmp(line, "SL_THICK", 8) == 0)
6787         {
6788           sscanf(line, "%*s %f", &st);
6789           st_d = TRUE;
6790         }
6791       else if(strncmp(line, "UNITS", 5) == 0)
6792         {
6793           sscanf(line, "%*s %s", units_string);
6794           u_d = TRUE;
6795         }
6796       else if(strncmp(line, "SIZE", 4) == 0)
6797         {
6798           sscanf(line, "%*s %d %d", &size[0], &size[1]);
6799           s_d = TRUE;
6800         }
6801       else if(strncmp(line, "FS_X_RAS", 8) == 0)
6802         {
6803           sscanf(line, "%*s %f %f %f", &x_r, &x_a, &x_s);
6804           x_ras_d = TRUE;
6805         }
6806       else if(strncmp(line, "FS_Y_RAS", 8) == 0)
6807         {
6808           sscanf(line, "%*s %f %f %f", &y_r, &y_a, &y_s);
6809           y_ras_d = TRUE;
6810         }
6811       else if(strncmp(line, "FS_Z_RAS", 8) == 0)
6812         {
6813           sscanf(line, "%*s %f %f %f", &z_r, &z_a, &z_s);
6814           z_ras_d = TRUE;
6815         }
6816       else if(strncmp(line, "FS_C_RAS", 8) == 0)
6817         {
6818           sscanf(line, "%*s %f %f %f", &c_r, &c_a, &c_s);
6819           c_ras_d = TRUE;
6820         }
6821       else if(strncmp(line, "DATA_TYPE", 9) == 0)
6822         {
6823           strcpy(data_type_string, &line[10]);
6824           dt_d = TRUE;
6825         }
6826       else if(strncmp(line, "ORIENTATION", 11) == 0)
6827         {
6828           sscanf(line, "%*s %s", orientation_string);
6829           strcpy(os_orig, orientation_string);
6830           o_d = TRUE;
6831         }
6832       else if(strncmp(line, "FILE_OFFSET", 11) == 0)
6833         {
6834           sscanf(line, "%*s %d", &file_offset);
6835         }
6836       else
6837         {
6838         }
6839 
6840     }
6841 
6842   fclose(fp);
6843 
6844   if(!(path_d && ipr_d && st_d && s_d))
6845     {
6846       errno = 0;
6847       ErrorPrintf
6848         (ERROR_BADPARM, "gdfRead(): missing field(s) from %s:", fname);
6849       if(!path_d)
6850         ErrorPrintf(ERROR_BADPARM, "  IMAGE_FILE_PATH");
6851       if(!ipr_d)
6852         ErrorPrintf(ERROR_BADPARM, "  IP_RES");
6853       if(!st_d)
6854         ErrorPrintf(ERROR_BADPARM, "  SL_THICK");
6855       if(!s_d)
6856         ErrorPrintf(ERROR_BADPARM, "  SIZE");
6857       return(NULL);
6858     }
6859 
6860   if(!(o_d))
6861     {
6862       if(x_ras_d && y_ras_d && z_ras_d)
6863         {
6864           printf("missing field ORIENTATION in file %s, "
6865                  "but you've got {xyz}_{ras}, so never mind\n", fname);
6866         }
6867       else
6868         {
6869           printf
6870             ("missing field ORIENTATION in file %s; assuming 'coronal'\n",
6871              fname);
6872           sprintf(orientation_string, "coronal");
6873         }
6874     }
6875 
6876   if(!(dt_d))
6877     {
6878       printf("missing field DATA_TYPE in file %s; assuming 'short'\n", fname);
6879       sprintf(data_type_string, "short");
6880     }
6881 
6882   if(!(u_d))
6883     {
6884       printf("missing field UNITS in file %s; assuming 'mm'\n", fname);
6885       sprintf(units_string, "mm");
6886     }
6887 
6888   StrLower(data_type_string);
6889   StrLower(orientation_string);
6890   StrLower(units_string);
6891 
6892   /* --- data type --- */
6893   if(strcmp(data_type_string, "short") == 0)
6894     data_type = MRI_SHORT;
6895   else if(strcmp(data_type_string, "float") == 0)
6896     data_type = MRI_FLOAT;
6897   else if(strcmp(data_type_string, "unsigned char") == 0)
6898     data_type = MRI_UCHAR;
6899   else
6900     {
6901       errno = 0;
6902       ErrorReturn
6903         (NULL,
6904          (ERROR_BADPARM,
6905           "gdfRead(): unknown data type '%s'", data_type_string));
6906     }
6907 
6908   /* --- orientation --- */
6909   or = strrchr(orientation_string, ' ');
6910   or = (or == NULL ? orientation_string : or+1);
6911   if(strncmp(or, "cor", 3) == 0)
6912     orientation = MRI_CORONAL;
6913   else if(strncmp(or, "sag", 3) == 0)
6914     orientation = MRI_SAGITTAL;
6915   else if(strncmp(or, "ax", 2) == 0 || strncmp(or, "hor", 3) == 0)
6916     orientation = MRI_HORIZONTAL;
6917   else if(!(x_ras_d && y_ras_d && z_ras_d))
6918     {
6919       errno = 0;
6920       ErrorReturn(NULL,
6921                   (ERROR_BADPARM,
6922                    "gdfRead(): can't determine orientation from string '%s'",
6923                    os_orig));
6924     }
6925 
6926   if(strcmp(units_string, "mm") == 0)
6927     units_factor = 1.0;
6928   else if(strcmp(units_string, "cm") == 0)
6929     units_factor = 1.0;
6930   else if(strcmp(units_string, "m") == 0)
6931     units_factor = 100.0;
6932   else
6933     {
6934       errno = 0;
6935       ErrorReturn
6936         (NULL,
6937          (ERROR_BADPARM, "gdfRead(): unknown units '%s'", units_string));
6938     }
6939 
6940   ipr[0] /= units_factor;
6941   ipr[1] /= units_factor;
6942   st /= units_factor;
6943 
6944   strcpy(file_path_1, file_path);
6945   c = strrchr(file_path_1, '*');
6946   if(c == NULL)
6947     {
6948       errno = 0;
6949       ErrorReturn(NULL,
6950                   (ERROR_BADPARM,
6951                    "gdfRead(): file path %s does not contain '*'\n",
6952                    file_path));
6953     }
6954 
6955   *c = '\0';
6956   c++;
6957   strcpy(file_path_2, c);
6958 
6959 #if 0
6960 
6961   /* cardviews takes IMAGE_FILE_PATH relative to the working */
6962   /* directory -- so we skip this step - ch                  */
6963 
6964   /* ----- relative path -- go from directory with the .gdf file ----- */
6965   if(file_path_1[0] != '/')
6966     {
6967 
6968       char gdf_path[STRLEN];
6969 
6970       if(fname[0] == '/')
6971         sprintf(gdf_path, "%s", fname);
6972       else
6973         sprintf(gdf_path, "./%s", fname);
6974 
6975       c = strrchr(gdf_path, '/');
6976       c[1] = '\0';
6977 
6978       strcat(gdf_path, file_path_1);
6979       strcpy(file_path_1, gdf_path);
6980 
6981     }
6982 #endif
6983 
6984   pad_zeros_flag = FALSE;
6985 
6986   n_files = 0;
6987   do
6988     {
6989       n_files++;
6990       sprintf(fname_use, "%s%d%s", file_path_1, n_files, file_path_2);
6991     } while(FileExists(fname_use));
6992 
6993   /* ----- try padding the zeros if no files are found ----- */
6994   if(n_files == 1)
6995     {
6996 
6997       pad_zeros_flag = TRUE;
6998 
6999       n_files = 0;
7000       do
7001         {
7002           n_files++;
7003           sprintf(fname_use, "%s%03d%s", file_path_1, n_files, file_path_2);
7004         } while(FileExists(fname_use));
7005 
7006       /* ----- still a problem? ----- */
7007       if(n_files == 1)
7008         {
7009           errno = 0;
7010           ErrorReturn(NULL, (ERROR_BADFILE,
7011                              "gdfRead(): can't find file %s%d%s or %s\n",
7012                              file_path_1, 1, file_path_2, fname_use));
7013         }
7014 
7015     }
7016 
7017   n_files--;
7018 
7019   if(read_volume)
7020     mri = MRIallocSequence(size[0], size[1], n_files, data_type, 1);
7021   else
7022     mri = MRIallocHeader(size[0], size[1], n_files, data_type);
7023 
7024   mri->xsize = ipr[0];
7025   mri->ysize = ipr[1];
7026   mri->zsize = st;
7027 
7028   mri->xend = mri->width  * mri->xsize / 2.0;
7029   mri->xstart = -mri->xend;
7030   mri->yend = mri->height * mri->ysize / 2.0;
7031   mri->ystart = -mri->yend;
7032   mri->zend = mri->depth  * mri->zsize / 2.0;
7033   mri->zstart = -mri->zend;
7034 
7035   strcpy(mri->fname, fname);
7036 
7037   /* --- set volume orientation --- */
7038   if(x_ras_d && y_ras_d && z_ras_d)
7039     {
7040       mri->x_r = x_r;  mri->x_a = x_a;  mri->x_s = x_s;
7041       mri->y_r = y_r;  mri->y_a = y_a;  mri->y_s = y_s;
7042       mri->z_r = z_r;  mri->z_a = z_a;  mri->z_s = z_s;
7043       mri->ras_good_flag = TRUE;
7044     }
7045   else
7046     {
7047       /*
7048          direction cosine is not set.  we pick a particular kind
7049          of direction cosine.  If the volume is different you have
7050          to modify (how?)
7051       */
7052       if (setDirectionCosine(mri, orientation) != NO_ERROR)
7053         {
7054           MRIfree(&mri);
7055           return NULL;
7056         }
7057       printf("warning: gdf volume may be incorrectly oriented\n");
7058     }
7059 
7060   /* --- set volume center --- */
7061   if(c_ras_d)
7062     {
7063       mri->c_r = c_r;  mri->c_a = c_a;  mri->c_s = c_s;
7064     }
7065   else
7066     {
7067       mri->c_r = mri->c_a = mri->c_s = 0.0;
7068       printf("warning: gdf volume may be incorrectly centered\n");
7069     }
7070 
7071   if(!read_volume)
7072     return(mri);
7073 
7074   if(mri->type == MRI_UCHAR)
7075     {
7076       ucbuf = (unsigned char *)malloc(mri->width);
7077       if(ucbuf == NULL)
7078         {
7079           MRIfree(&mri);
7080           errno = 0;
7081           ErrorReturn
7082             (NULL,
7083              (ERROR_NOMEMORY,
7084               "gdfRead(): error allocating %d bytes for read buffer",
7085               mri->width));
7086         }
7087     }
7088   else if(mri->type == MRI_SHORT)
7089     {
7090       sbuf = (short *)malloc(mri->width * sizeof(short));
7091       if(sbuf == NULL)
7092         {
7093           MRIfree(&mri);
7094           errno = 0;
7095           ErrorReturn
7096             (NULL,
7097              (ERROR_NOMEMORY,
7098               "gdfRead(): error allocating %d bytes for read buffer",
7099               mri->width * sizeof(short)));
7100         }
7101     }
7102   else if(mri->type == MRI_FLOAT)
7103     {
7104       fbuf = (float *)malloc(mri->width * sizeof(float));
7105       if(fbuf == NULL)
7106         {
7107           MRIfree(&mri);
7108           errno = 0;
7109           ErrorReturn
7110             (NULL,
7111              (ERROR_NOMEMORY,
7112               "gdfRead(): error allocating %d bytes for read buffer",
7113               mri->width * sizeof(float)));
7114         }
7115     }
7116   else
7117     {
7118       MRIfree(&mri);
7119       errno = 0;
7120       ErrorReturn(NULL, (ERROR_BADPARM,
7121                          "gdfRead(): internal error; data type %d "
7122                          "accepted but not supported in read",
7123                          mri->type));
7124     }
7125 
7126   for(i = 1;i <= n_files;i++)
7127     {
7128 
7129       if(pad_zeros_flag)
7130         sprintf(fname_use, "%s%03d%s", file_path_1, i, file_path_2);
7131       else
7132         sprintf(fname_use, "%s%d%s", file_path_1, i, file_path_2);
7133 
7134       fp = fopen(fname_use, "r");
7135       if(fp == NULL)
7136         {
7137           if(mri->type == MRI_UCHAR)
7138             free(ucbuf);
7139           if(mri->type == MRI_SHORT)
7140             free(sbuf);
7141           if(mri->type == MRI_FLOAT)
7142             free(fbuf);
7143           MRIfree(&mri);
7144           errno = 0;
7145           ErrorReturn
7146             (NULL,
7147              (ERROR_BADFILE,
7148               "gdfRead(): error opening file %s", fname_use));
7149         }
7150 
7151       fseek(fp, file_offset, SEEK_SET);
7152 
7153       if(mri->type == MRI_UCHAR)
7154         {
7155           for(j = 0;j < mri->height;j++)
7156             {
7157               if(fread(ucbuf, 1, mri->width, fp) != mri->width)
7158                 {
7159                   free(ucbuf);
7160                   MRIfree(&mri);
7161                   errno = 0;
7162                   ErrorReturn(NULL, (ERROR_BADFILE,
7163                                      "gdfRead(): error reading from file %s",
7164                                      fname_use));
7165                 }
7166               for(k = 0;k < mri->width;k++)
7167                 MRIvox(mri, k, j, i-1) = ucbuf[k];
7168             }
7169         }
7170 
7171       if(mri->type == MRI_SHORT)
7172         {
7173           for(j = 0;j < mri->height;j++)
7174             {
7175               if(fread(sbuf, sizeof(short), mri->width, fp) != mri->width)
7176                 {
7177                   free(sbuf);
7178                   MRIfree(&mri);
7179                   errno = 0;
7180                   ErrorReturn(NULL, (ERROR_BADFILE,
7181                                      "gdfRead(): error reading from file %s",
7182                                      fname_use));
7183                 }
7184 #if (BYTE_ORDER == LITTLE_ENDIAN)
7185               for(k = 0;k < mri->width;k++)
7186                 MRISvox(mri, k, j, i-1) = orderShortBytes(sbuf[k]);
7187 #else
7188               for(k = 0;k < mri->width;k++)
7189                 MRISvox(mri, k, j, i-1) = sbuf[k];
7190 #endif
7191             }
7192         }
7193 
7194       if(mri->type == MRI_FLOAT)
7195         {
7196           for(j = 0;j < mri->height;j++)
7197             {
7198               if(fread(fbuf, sizeof(float), mri->width, fp) != mri->width)
7199                 {
7200                   free(fbuf);
7201                   MRIfree(&mri);
7202                   errno = 0;
7203                   ErrorReturn
7204                     (NULL,
7205                      (ERROR_BADFILE,
7206                       "gdfRead(): error reading from file %s", fname_use));
7207                 }
7208 #if (BYTE_ORDER == LITTLE_ENDIAN)
7209               for(k = 0;k < mri->width;k++)
7210                 MRIFvox(mri, k, j, i-1) = orderFloatBytes(fbuf[k]);
7211 #else
7212               for(k = 0;k < mri->width;k++)
7213                 MRIFvox(mri, k, j, i-1) = fbuf[k];
7214 #endif
7215             }
7216         }
7217 
7218       fclose(fp);
7219 
7220     }
7221 
7222   if(mri->type == MRI_UCHAR)
7223     free(ucbuf);
7224   if(mri->type == MRI_SHORT)
7225     free(sbuf);
7226   if(mri->type == MRI_FLOAT)
7227     free(fbuf);
7228 
7229   return(mri);
7230 
7231 } /* end gdfRead() */
7232 
7233 static int gdfWrite(MRI *mri, char *fname)
7234 {
7235 
7236   FILE *fp;
7237   int i, j;
7238   char im_fname[STRLEN];
7239   unsigned char *buf;
7240   int buf_size = 0;
7241 
7242   if(strlen(mri->gdf_image_stem) == 0)
7243     {
7244       errno = 0;
7245       ErrorReturn
7246         (ERROR_BADPARM,
7247          (ERROR_BADPARM, "GDF write attempted without GDF image stem"));
7248     }
7249 
7250   if(mri->nframes != 1)
7251     {
7252       errno = 0;
7253       ErrorReturn(ERROR_BADPARM, (ERROR_BADPARM,
7254                                   "GDF write attempted with %d frames "
7255                                   "(supported only for 1 frame)",
7256                                   mri->nframes));
7257     }
7258 
7259   /* ----- type checks first ----- */
7260 
7261   if(mri->type != MRI_UCHAR &&
7262      mri->type != MRI_FLOAT &&
7263      mri->type != MRI_SHORT)
7264     {
7265       errno = 0;
7266       ErrorReturn
7267         (ERROR_BADPARM,
7268          (ERROR_BADPARM,
7269           "gdfWrite(): bad data type (%d) for GDF write "
7270           "(only uchar, float, short supported)", mri->type));
7271     }
7272 
7273   /* ----- then write the image files ----- */
7274 
7275   printf("writing GDF image files...\n");
7276 
7277   if(mri->type == MRI_UCHAR)
7278     buf_size = mri->width * sizeof(unsigned char);
7279   if(mri->type == MRI_FLOAT)
7280     buf_size = mri->width * sizeof(float);
7281   if(mri->type == MRI_SHORT)
7282     buf_size = mri->width * sizeof(short);
7283 
7284   buf = (unsigned char *)malloc(buf_size);
7285   if(buf == NULL)
7286     {
7287       errno = 0;
7288       ErrorReturn
7289         (ERROR_NO_MEMORY,
7290          (ERROR_NO_MEMORY,
7291           "gdfWrite(): no memory for voxel write buffer"));
7292     }
7293 
7294   for(i = 0;i < mri->depth;i++)
7295     {
7296 
7297       sprintf(im_fname, "%s_%d.img", mri->gdf_image_stem, i+1);
7298       fp = fopen(im_fname, "w");
7299       if(fp == NULL)
7300         {
7301           free(buf);
7302           errno = 0;
7303           ErrorReturn
7304             (ERROR_BADFILE,
7305              (ERROR_BADFILE,
7306               "gdfWrite(): error opening file %s", im_fname));
7307         }
7308 
7309       for(j = 0;j < mri->height;j++)
7310         {
7311           memcpy(buf, mri->slices[i][j], buf_size);
7312 #if (BYTE_ORDER == LITTLE_ENDIAN)
7313           if(mri->type == MRI_FLOAT)
7314             byteswapbuffloat(buf, buf_size);
7315           if(mri->type == MRI_SHORT)
7316             byteswapbufshort(buf, buf_size);
7317 #endif
7318           fwrite(buf, 1, buf_size, fp);
7319         }
7320 
7321       fclose(fp);
7322 
7323     }
7324 
7325   free(buf);
7326 
7327   /* ----- and finally the info file ----- */
7328 
7329   printf("writing GDF info file...\n");
7330 
7331   fp = fopen(fname, "w");
7332   if(fp == NULL)
7333     {
7334       errno = 0;
7335       ErrorReturn
7336         (ERROR_BADFILE,
7337          (ERROR_BADFILE, "gdfWrite(): error opening file %s", fname));
7338     }
7339 
7340   fprintf(fp, "GDF FILE VERSION3\n");
7341   fprintf(fp, "START MAIN HEADER\n");
7342   fprintf(fp, "IMAGE_FILE_PATH %s_*.img\n", mri->gdf_image_stem);
7343   fprintf(fp, "SIZE %d %d\n", mri->width, mri->height);
7344   fprintf(fp, "IP_RES %g %g\n", mri->xsize, mri->ysize);
7345   fprintf(fp, "SL_THICK %g\n", mri->zsize);
7346   if(mri->ras_good_flag)
7347     {
7348       fprintf(fp, "FS_X_RAS %f %f %f\n", mri->x_r, mri->x_a, mri->x_s);
7349       fprintf(fp, "FS_Y_RAS %f %f %f\n", mri->y_r, mri->y_a, mri->y_s);
7350       fprintf(fp, "FS_Z_RAS %f %f %f\n", mri->z_r, mri->z_a, mri->z_s);
7351       fprintf(fp, "FS_C_RAS %f %f %f\n", mri->c_r, mri->c_a, mri->c_s);
7352     }
7353   fprintf(fp, "FILE_OFFSET 0\n");
7354   if(mri->type == MRI_UCHAR)
7355     fprintf(fp, "DATA_TYPE unsigned char\n");
7356   if(mri->type == MRI_FLOAT)
7357     fprintf(fp, "DATA_TYPE float\n");
7358   if(mri->type == MRI_SHORT)
7359     fprintf(fp, "DATA_TYPE short\n");
7360   fprintf(fp, "END MAIN HEADER\n");
7361 
7362   fclose(fp);
7363 
7364   return(NO_ERROR);
7365 
7366 }
7367 
7368 static int parc_fill(short label_value, short seed_x, short seed_y)
7369 {
7370 
7371   if(seed_x < 0 || seed_x >= 512 || seed_y < 0 || seed_y >= 512)
7372     return(NO_ERROR);
7373 
7374   if(cma_field[seed_x][seed_y] == label_value)
7375     return(NO_ERROR);
7376 
7377   cma_field[seed_x][seed_y] = label_value;
7378 
7379   parc_fill(label_value, seed_x + 1, seed_y    );
7380   parc_fill(label_value, seed_x - 1, seed_y    );
7381   parc_fill(label_value, seed_x    , seed_y + 1);
7382   parc_fill(label_value, seed_x    , seed_y - 1);
7383 
7384   return(NO_ERROR);
7385 
7386 } /* end parc_fill() */
7387 
7388 static int register_unknown_label(char *label)
7389 {
7390 
7391   int i;
7392 
7393   if(n_unknown_labels == MAX_UNKNOWN_LABELS)
7394     return(NO_ERROR);
7395 
7396   for(i = 0;i < n_unknown_labels;i++)
7397     {
7398       if(strcmp(unknown_labels[i], label) == 0)
7399         return(NO_ERROR);
7400     }
7401 
7402   strcpy(unknown_labels[n_unknown_labels], label);
7403   n_unknown_labels++;
7404 
7405   return(NO_ERROR);
7406 
7407 } /* end register_unknown_label() */
7408 
7409 static int clear_unknown_labels(void)
7410 {
7411 
7412   n_unknown_labels = 0;
7413 
7414   return(NO_ERROR);
7415 
7416 } /* end clear_unknown_labels() */
7417 
7418 static int print_unknown_labels(char *prefix)
7419 {
7420 
7421   int i;
7422 
7423   for(i = 0;i < n_unknown_labels;i++)
7424     printf("%s%s\n", prefix, unknown_labels[i]);
7425 
7426   return(NO_ERROR);
7427 
7428 } /* end print_unknown_labels() */
7429 
7430 /* replaced 25 Feb 2003 ch */
7431 #if 0
7432 static int read_otl_file(FILE *fp,
7433                          MRI *mri,
7434                          int slice,
7435                          mriColorLookupTableRef color_table,
7436                          int fill_flag,
7437                          int translate_label_flag,
7438                          int zero_outlines_flag)
7439 {
7440   int n_outlines = -1;
7441   int n_rows, n_cols;
7442   char label[STRLEN], label_to_compare[STRLEN];
7443   int seed_x, seed_y;
7444   char line[STRLEN];
7445   int main_header_flag;
7446   int i, j;
7447   int gdf_header_flag;
7448   char type[STRLEN], global_type[STRLEN];
7449   char *c;
7450   short *points;
7451   int n_read;
7452   short label_value;
7453   float scale_x, scale_y;
7454   int source_x, source_y;
7455   char alt_compare[STRLEN];
7456   int empty_label_flag;
7457   int ascii_short_flag;
7458   int row;
7459   char *translate_start;
7460   int internal_structures_flag = FALSE;
7461 
7462   for(i = 0;i < 512;i++)
7463     memset(cma_field[i], 0x00, 512 * 2);
7464 
7465   fgets(line, STRLEN, fp);
7466   if(strncmp(line, "GDF FILE VERSION", 15) != 0)
7467     {
7468       errno = 0;
7469       ErrorReturn
7470         (ERROR_BADFILE,
7471          (ERROR_BADFILE,
7472           "otl slice %s does not appear to be a GDF file", slice));
7473     }
7474 
7475   main_header_flag = FALSE;
7476   while(!main_header_flag)
7477     {
7478       if(feof(fp))
7479         {
7480           errno = 0;
7481           ErrorReturn
7482             (ERROR_BADFILE,
7483              (ERROR_BADFILE,
7484               "premature EOF () in otl file %d", slice));
7485         }
7486       fgets(line, STRLEN, fp);
7487       if(strncmp(line, "START MAIN HEADER", 17) == 0)
7488         main_header_flag = TRUE;
7489     }
7490 
7491   n_cols = -1;
7492   type[0] = '\0';
7493   global_type[0] = '\0';
7494 
7495   while(main_header_flag)
7496     {
7497       if(feof(fp))
7498         {
7499           errno = 0;
7500           ErrorReturn
7501             (ERROR_BADFILE,
7502              (ERROR_BADFILE,
7503               "premature EOF (in main header) in otl file %d", slice));
7504         }
7505       fgets(line, STRLEN, fp);
7506       if(strncmp(line, "END MAIN HEADER", 15) == 0)
7507         main_header_flag = FALSE;
7508       if(strncmp(line, "ONUM ", 5) == 0)
7509         sscanf(line, "%*s %d", &n_outlines);
7510       if(strncmp(line, "COL_NUM", 7) == 0)
7511         sscanf(line, "%*s %d", &n_cols);
7512       if(strncmp(line, "TYPE", 4) == 0)
7513         {
7514           strcpy(global_type, &(line[5]));
7515           c = strrchr(global_type, '\n');
7516           if(c != NULL)
7517             *c = '\0';
7518         }
7519     }
7520 
7521   if(n_outlines == -1)
7522     {
7523       errno = 0;
7524       ErrorReturn
7525         (ERROR_BADPARM,
7526          (ERROR_BADPARM,
7527           "bad or undefined ONUM in otl file %d", slice));
7528     }
7529 
7530   for(i = 0;i < n_outlines;i++)
7531     {
7532       if(feof(fp))
7533         {
7534           errno = 0;
7535           ErrorReturn
7536             (ERROR_BADFILE,
7537              (ERROR_BADFILE,
7538               "premature EOF (ready for next outline) in otl file %d",
7539               slice));
7540         }
7541 
7542       gdf_header_flag = FALSE;
7543 
7544       while(!gdf_header_flag)
7545         {
7546           if(feof(fp))
7547             {
7548               errno = 0;
7549               ErrorReturn
7550                 (ERROR_BADFILE,
7551                  (ERROR_BADFILE,
7552                   "premature EOF (searching for gdf header) "
7553                   "in otl file %d", slice));
7554             }
7555           fgets(line, STRLEN, fp);
7556           if(strncmp(line, "START GDF HEADER", 16) == 0)
7557             gdf_header_flag = TRUE;
7558         }
7559 
7560       n_rows = -1;
7561       seed_x = seed_y = -1;
7562       label[0] = '\0';
7563       type[0] = '\0';
7564 
7565       empty_label_flag = 0;
7566 
7567       while(gdf_header_flag)
7568         {
7569 
7570           if(feof(fp))
7571             {
7572               errno = 0;
7573               ErrorReturn
7574                 (ERROR_BADFILE,
7575                  (ERROR_BADFILE,
7576                   "premature EOF (in gdf header) in otl file %d",
7577                   slice));
7578             }
7579           fgets(line, STRLEN, fp);
7580           if(strncmp(line, "END GDF HEADER", 14) == 0)
7581             gdf_header_flag = FALSE;
7582           if(strncmp(line, "ROW_NUM", 7) == 0)
7583             sscanf(line, "%*s %d", &n_rows);
7584           if(strncmp(line, "COL_NUM", 7) == 0)
7585             sscanf(line, "%*s %d", &n_cols);
7586           if(strncmp(line, "TYPE", 4) == 0)
7587             {
7588               strcpy(type, &(line[5]));
7589               c = strrchr(type, '\n');
7590               if(c != NULL)
7591                 *c = '\0';
7592             }
7593           if(strncmp(line, "SEED", 4) == 0)
7594             sscanf(line, "%*s %d %d", &seed_x, &seed_y);
7595           if(strncmp(line, "LABEL", 5) == 0)
7596             {
7597 
7598               strcpy(label, &(line[6]));
7599               c = strrchr(label, '\n');
7600               if(c != NULL)
7601                 *c = '\0';
7602 
7603               /* exterior -> cortex, if desired */
7604               if(translate_label_flag)
7605                 {
7606                   translate_start = strstr(label, "Exterior");
7607                   if(translate_start != NULL)
7608                     sprintf(translate_start, "Cortex");
7609                   else
7610                     {
7611                       translate_start = strstr(label, "exterior");
7612                       if(translate_start != NULL)
7613                         sprintf(translate_start, "cortex");
7614                     }
7615                 }
7616 
7617               /* warning if there's an "exterior" or
7618                  "cortex" after any other label */
7619               if(strstr(label, "Exterior") == 0 \
7620                  || strstr(label, "exterior") == 0 \
7621                  || strstr(label, "Cortex") == 0 \
7622                  || strstr(label, "cortex") == 0)
7623                 {
7624                   if(internal_structures_flag)
7625                     printf("WARNING: label \"%s\" following "
7626                            "non-exterior labels in slice %d\n",
7627                            label, slice);
7628                   internal_structures_flag = FALSE;
7629                 }
7630               else
7631                 internal_structures_flag = TRUE;
7632 
7633             }
7634 
7635         }
7636 
7637       if(n_rows < 0)
7638         {
7639           errno = 0;
7640           ErrorReturn(ERROR_BADPARM,
7641                       (ERROR_BADPARM,
7642                        "bad or undefined ROW_NUM in otl file %d", slice));
7643         }
7644 
7645       if(n_cols != 2)
7646         {
7647           errno = 0;
7648           ErrorReturn(ERROR_BADPARM,
7649                       (ERROR_BADPARM,
7650                        "bad or undefined COL_NUM in otl file %d", slice));
7651         }
7652 
7653       if(label[0] == '\0')
7654         {
7655           empty_label_flag = 1;
7656           errno = 0;
7657           ErrorPrintf
7658             (ERROR_BADPARM,
7659              "empty LABEL in otl file %d (outline %d)", slice, i);
7660         }
7661 
7662       if(seed_x < 0 || seed_x >= 512 || seed_y < 0 || seed_y >= 512)
7663         {
7664           errno = 0;
7665           ErrorReturn(ERROR_BADPARM,
7666                       (ERROR_BADPARM,
7667                        "bad or undefined SEED in otl file %d", slice));
7668         }
7669 
7670       if(type[0] == '\0')
7671         strcpy(type, global_type);
7672 
7673       if(strcmp(type, "ascii short") == 0)
7674         ascii_short_flag = TRUE;
7675       else if(strcmp(type, "short") == 0)
7676         ascii_short_flag = FALSE;
7677       else if(type[0] == '\0')
7678         {
7679           errno = 0;
7680           ErrorReturn(ERROR_UNSUPPORTED,
7681                       (ERROR_UNSUPPORTED,
7682                        "undefined TYPE in otl file %d", slice));
7683         }
7684       else
7685         {
7686           errno = 0;
7687           ErrorReturn(ERROR_UNSUPPORTED,
7688                       (ERROR_UNSUPPORTED,
7689                        "unsupported TYPE \"%s\" in otl file %d", type, slice));
7690         }
7691 
7692       do
7693         {
7694           fgets(line, STRLEN, fp);
7695           if(feof(fp))
7696             {
7697               errno = 0;
7698               ErrorReturn
7699                 (ERROR_BADFILE,
7700                  (ERROR_BADFILE,
7701                   "premature EOF (searching for points) in otl file %d",
7702                   slice));
7703             }
7704         } while(strncmp(line, "START POINTS", 12) != 0);
7705 
7706       points = (short *)malloc(2 * n_rows * sizeof(short));
7707       if(points == NULL)
7708         {
7709           errno = 0;
7710           ErrorReturn
7711             (ERROR_NOMEMORY,
7712              (ERROR_NOMEMORY,
7713               "error allocating memory for points in otl file %d", slice));
7714         }
7715 
7716       if(ascii_short_flag)
7717         {
7718           for(row = 0;row < n_rows;row++)
7719             {
7720               fgets(line, STRLEN, fp);
7721               if(feof(fp))
7722                 {
7723                   free(points);
7724                   errno = 0;
7725                   ErrorReturn
7726                     (ERROR_BADFILE,
7727                      (ERROR_BADFILE,
7728                       "premature end of file while reading points "
7729                       "from otl file %d",
7730                       slice));
7731                 }
7732               sscanf(line, "%hd %hd", &(points[2*row]), &(points[2*row+1]));
7733             }
7734         }
7735       else
7736         {
7737           n_read = fread(points, 2, n_rows * 2, fp);
7738           if(n_read != n_rows * 2)
7739             {
7740               free(points);
7741               errno = 0;
7742               ErrorReturn(ERROR_BADFILE,
7743                           (ERROR_BADFILE,
7744                            "error reading points from otl file %d", slice));
7745             }
7746 #if (BYTE_ORDER == LITTLE_ENDIAN)
7747           swab(points, points, 2 * n_rows * sizeof(short));
7748 #endif
7749         }
7750 
7751       fgets(line, STRLEN, fp);
7752       if(strncmp(line, "END POINTS", 10) != 0)
7753         {
7754           free(points);
7755           errno = 0;
7756           ErrorReturn
7757             (ERROR_BADFILE,
7758              (ERROR_BADFILE,
7759               "error after points (\"END POINTS\" expected "
7760               "but not found) in otl file %d", slice));
7761         }
7762 
7763       if(!empty_label_flag)
7764         {
7765           strcpy(label_to_compare, label);
7766           for(j = 0;label_to_compare[j] != '\0';j++)
7767             {
7768               if(label_to_compare[j] == '\n')
7769                 label_to_compare[j] = '\0';
7770               if(label_to_compare[j] == ' ')
7771                 label_to_compare[j] = '-';
7772             }
7773 
7774           /* --- strip 'Left' and 'Right'; --- */
7775           strcpy(alt_compare, label_to_compare);
7776           StrLower(alt_compare);
7777           if(strncmp(alt_compare, "left-", 5) == 0)
7778             strcpy(alt_compare, &(label_to_compare[5]));
7779           else if(strncmp(alt_compare, "right-", 6) == 0)
7780             strcpy(alt_compare, &(label_to_compare[6]));
7781 
7782           /* --- strip leading and trailing spaces (now dashes) --- */
7783 
7784           /* leading */
7785           for(j = 0;label_to_compare[j] == '-';j++);
7786           if(label_to_compare[j] != '\0')
7787             {
7788               for(c = label_to_compare;*(c+j) != '\0';c++)
7789                 *c = *(c+j);
7790               *c = *(c+j);
7791             }
7792 
7793           /* trailing */
7794           for(j = strlen(label_to_compare) - 1;
7795               j >= 0 && label_to_compare[j] == '-';
7796               j--);
7797           if(j < 0) /* all dashes! */
7798             {
7799               /* for now, let this fall through to an unknown label */
7800             }
7801           else /* j is the index of the last non-dash character */
7802             {
7803               label_to_compare[j+1] = '\0';
7804             }
7805 
7806 
7807           label_value = -1;
7808           for(j = 0;j < color_table->mnNumEntries;j++)
7809             if(strcmp(color_table->maEntries[j].msLabel,
7810                       label_to_compare) == 0 ||
7811                strcmp(color_table->maEntries[j].msLabel, alt_compare) == 0)
7812               label_value = j;
7813 
7814           if(label_value == -1)
7815             {
7816               register_unknown_label(label);
7817             }
7818           else
7819             {
7820 
7821               for(j = 0;j < n_rows;j++)
7822                 cma_field[points[2*j]][points[2*j+1]] = label_value;
7823 
7824               if(fill_flag && label_value != 0)
7825                 parc_fill(label_value, seed_x, seed_y);
7826 
7827               if(zero_outlines_flag)
7828                 {
7829                   for(j = 0;j < n_rows;j++)
7830                     cma_field[points[2*j]][points[2*j+1]] = 0;
7831                 }
7832 
7833 
7834             }
7835 
7836         }
7837 
7838       free(points);
7839 
7840     }
7841 
7842   scale_x = 512 / mri->width;
7843   scale_y = 512 / mri->height;
7844 
7845   for(i = 0;i < mri->width;i++)
7846     for(j = 0;j < mri->height;j++)
7847       {
7848         source_x = (int)floor(scale_x * (float)i);
7849         source_y = (int)floor(scale_y * (float)j);
7850         if(source_x < 0)
7851           source_x = 0;
7852         if(source_x > 511)
7853           source_x = 511;
7854         if(source_y < 0)
7855           source_y = 0;
7856         if(source_y > 511)
7857           source_y = 511;
7858         MRISvox(mri, i, j, slice-1) = cma_field[source_x][source_y];
7859       }
7860 
7861   return(NO_ERROR);
7862 
7863 } /* end read_otl_file() */
7864 #endif
7865 
7866 static int read_otl_file(FILE *fp,
7867                          MRI *mri,
7868                          int slice,
7869                          mriColorLookupTableRef color_table,
7870                          int fill_flag,
7871                          int translate_label_flag,
7872                          int zero_outlines_flag)
7873 {
7874 
7875   int n_outlines = -1;
7876   int n_rows, n_cols;
7877   char label[STRLEN], label_to_compare[STRLEN];
7878   int seed_x, seed_y;
7879   char line[STRLEN];
7880   int main_header_flag;
7881   int i, j;
7882   int gdf_header_flag;
7883   char type[STRLEN], global_type[STRLEN];
7884   char *c;
7885   short *points;
7886   int n_read;
7887   short label_value;
7888   float scale_x, scale_y;
7889   int source_x, source_y;
7890   char alt_compare[STRLEN];
7891   int empty_label_flag;
7892   int ascii_short_flag;
7893   int row;
7894   char *translate_start;
7895   int internal_structures_flag = FALSE;
7896   CMAoutlineField *of;
7897 
7898   fgets(line, STRLEN, fp);
7899   if(strncmp(line, "GDF FILE VERSION", 15) != 0)
7900     {
7901       errno = 0;
7902       ErrorReturn(ERROR_BADFILE,
7903                   (ERROR_BADFILE,
7904                    "otl slice %s does not appear to be a GDF file", slice));
7905     }
7906 
7907   main_header_flag = FALSE;
7908   while(!main_header_flag)
7909     {
7910       if(feof(fp))
7911         {
7912           errno = 0;
7913           ErrorReturn
7914             (ERROR_BADFILE,
7915              (ERROR_BADFILE, "premature EOF () in otl file %d", slice));
7916         }
7917       fgets(line, STRLEN, fp);
7918       if(strncmp(line, "START MAIN HEADER", 17) == 0)
7919         main_header_flag = TRUE;
7920     }
7921 
7922   n_cols = -1;
7923   type[0] = '\0';
7924   global_type[0] = '\0';
7925 
7926   while(main_header_flag)
7927     {
7928       if(feof(fp))
7929         {
7930           errno = 0;
7931           ErrorReturn
7932             (ERROR_BADFILE,
7933              (ERROR_BADFILE,
7934               "premature EOF (in main header) in otl file %d", slice));
7935         }
7936       fgets(line, STRLEN, fp);
7937       if(strncmp(line, "END MAIN HEADER", 15) == 0)
7938         main_header_flag = FALSE;
7939       if(strncmp(line, "ONUM ", 5) == 0)
7940         sscanf(line, "%*s %d", &n_outlines);
7941       if(strncmp(line, "COL_NUM", 7) == 0)
7942         sscanf(line, "%*s %d", &n_cols);
7943       if(strncmp(line, "TYPE", 4) == 0)
7944         {
7945           strcpy(global_type, &(line[5]));
7946           c = strrchr(global_type, '\n');
7947           if(c != NULL)
7948             *c = '\0';
7949         }
7950     }
7951 
7952   if(n_outlines == -1)
7953     {
7954       errno = 0;
7955       ErrorReturn
7956         (ERROR_BADPARM,
7957          (ERROR_BADPARM,
7958           "bad or undefined ONUM in otl file %d", slice));
7959     }
7960 
7961   of = CMAoutlineFieldAlloc(2*mri->width, 2*mri->height);
7962   if(of == NULL)
7963     return(ERROR_NOMEMORY);
7964 
7965   for(i = 0;i < n_outlines;i++)
7966     {
7967       if(feof(fp))
7968         {
7969           CMAfreeOutlineField(&of);
7970           errno = 0;
7971           ErrorReturn
7972             (ERROR_BADFILE,
7973              (ERROR_BADFILE,
7974               "premature EOF (ready for next outline) in otl file %d", slice));
7975         }
7976 
7977       gdf_header_flag = FALSE;
7978 
7979       while(!gdf_header_flag)
7980         {
7981           if(feof(fp))
7982             {
7983               CMAfreeOutlineField(&of);
7984               errno = 0;
7985               ErrorReturn
7986                 (ERROR_BADFILE,
7987                  (ERROR_BADFILE,
7988                   "premature EOF (searching for gdf header) in otl file %d",
7989                   slice));
7990             }
7991           fgets(line, STRLEN, fp);
7992           if(strncmp(line, "START GDF HEADER", 16) == 0)
7993             gdf_header_flag = TRUE;
7994         }
7995 
7996       n_rows = -1;
7997       seed_x = seed_y = -1;
7998       label[0] = '\0';
7999       type[0] = '\0';
8000 
8001       empty_label_flag = 0;
8002 
8003       while(gdf_header_flag)
8004         {
8005 
8006           if(feof(fp))
8007             {
8008               CMAfreeOutlineField(&of);
8009               errno = 0;
8010               ErrorReturn
8011                 (ERROR_BADFILE,
8012                  (ERROR_BADFILE,
8013                   "premature EOF (in gdf header) in otl file %d", slice));
8014             }
8015           fgets(line, STRLEN, fp);
8016           if(strncmp(line, "END GDF HEADER", 14) == 0)
8017             gdf_header_flag = FALSE;
8018           // getting rows, cols, type
8019           if(strncmp(line, "ROW_NUM", 7) == 0)
8020             sscanf(line, "%*s %d", &n_rows);
8021           if(strncmp(line, "COL_NUM", 7) == 0)
8022             sscanf(line, "%*s %d", &n_cols);
8023           if(strncmp(line, "TYPE", 4) == 0)
8024             {
8025               strcpy(type, &(line[5]));
8026               c = strrchr(type, '\n');
8027               if(c != NULL)
8028                 *c = '\0';
8029             }
8030           if(strncmp(line, "SEED", 4) == 0)
8031             sscanf(line, "%*s %d %d", &seed_x, &seed_y);
8032           if(strncmp(line, "LABEL", 5) == 0)
8033             {
8034 
8035               strcpy(label, &(line[6]));
8036               c = strrchr(label, '\n');
8037               if(c != NULL)
8038                 *c = '\0';
8039 
8040               /* exterior -> cortex, if desired */
8041               if(translate_label_flag)
8042                 {
8043                   translate_start = strstr(label, "Exterior");
8044                   if(translate_start != NULL)
8045                     sprintf(translate_start, "Cortex");
8046                   else
8047                     {
8048                       translate_start = strstr(label, "exterior");
8049                       if(translate_start != NULL)
8050                         sprintf(translate_start, "cortex");
8051                     }
8052                 }
8053 
8054               /* warning if there's an "exterior" or
8055                  "cortex" after any other label */
8056               if(strstr(label, "Exterior") == 0 \
8057                  || strstr(label, "exterior") == 0 \
8058                  || strstr(label, "Cortex") == 0 \
8059                  || strstr(label, "cortex") == 0)
8060                 {
8061                   if(internal_structures_flag)
8062                     printf("WARNING: label \"%s\" following "
8063                            "non-exterior labels in slice %d\n",
8064                            label, slice);
8065                   internal_structures_flag = FALSE;
8066                 }
8067               else
8068                 internal_structures_flag = TRUE;
8069 
8070             }
8071 
8072         }
8073 
8074       if(n_rows < 0)
8075         {
8076           CMAfreeOutlineField(&of);
8077           errno = 0;
8078           ErrorReturn(ERROR_BADPARM,
8079                       (ERROR_BADPARM,
8080                        "bad or undefined ROW_NUM in otl file %d", slice));
8081         }
8082 
8083       if(n_cols != 2)
8084         {
8085           CMAfreeOutlineField(&of);
8086           errno = 0;
8087           ErrorReturn(ERROR_BADPARM,
8088                       (ERROR_BADPARM,
8089                        "bad or undefined COL_NUM in otl file %d", slice));
8090         }
8091 
8092       if(label[0] == '\0')
8093         {
8094           empty_label_flag = 1;
8095           errno = 0;
8096           ErrorPrintf(ERROR_BADPARM,
8097                       "empty LABEL in otl file %d (outline %d)", slice, i);
8098         }
8099 
8100       if(seed_x < 0 || seed_x >= 512 || seed_y < 0 || seed_y >= 512)
8101         {
8102           CMAfreeOutlineField(&of);
8103           errno = 0;
8104           ErrorReturn(ERROR_BADPARM,
8105                       (ERROR_BADPARM,
8106                        "bad or undefined SEED in otl file %d", slice));
8107         }
8108 
8109       if(type[0] == '\0')
8110         strcpy(type, global_type);
8111 
8112       if(strcmp(type, "ascii short") == 0)
8113         ascii_short_flag = TRUE;
8114       else if(strcmp(type, "short") == 0)
8115         ascii_short_flag = FALSE;
8116       else if(type[0] == '\0')
8117         {
8118           CMAfreeOutlineField(&of);
8119           errno = 0;
8120           ErrorReturn(ERROR_UNSUPPORTED,
8121                       (ERROR_UNSUPPORTED,
8122                        "undefined TYPE in otl file %d", slice));
8123         }
8124       else
8125         {
8126           CMAfreeOutlineField(&of);
8127           errno = 0;
8128           ErrorReturn(ERROR_UNSUPPORTED,
8129                       (ERROR_UNSUPPORTED,
8130                        "unsupported TYPE \"%s\" in otl file %d", type, slice));
8131         }
8132 
8133       do
8134         {
8135           fgets(line, STRLEN, fp);
8136           if(feof(fp))
8137             {
8138               CMAfreeOutlineField(&of);
8139               errno = 0;
8140               ErrorReturn
8141                 (ERROR_BADFILE,
8142                  (ERROR_BADFILE,
8143                   "premature EOF (searching for points) in otl file %d",
8144                   slice));
8145             }
8146         } while(strncmp(line, "START POINTS", 12) != 0);
8147 
8148       points = (short *)malloc(2 * n_rows * sizeof(short));
8149       if(points == NULL)
8150         {
8151           CMAfreeOutlineField(&of);
8152           errno = 0;
8153           ErrorReturn
8154             (ERROR_NOMEMORY,
8155              (ERROR_NOMEMORY,
8156               "error allocating memory for points in otl file %d", slice));
8157         }
8158 
8159       if(ascii_short_flag)
8160         {
8161           for(row = 0;row < n_rows;row++)
8162             {
8163               fgets(line, STRLEN, fp);
8164               if(feof(fp))
8165                 {
8166                   free(points);
8167                   CMAfreeOutlineField(&of);
8168                   errno = 0;
8169                   ErrorReturn
8170                     (ERROR_BADFILE,
8171                      (ERROR_BADFILE,
8172                       "premature end of file while reading "
8173                       "points from otl file %d",
8174                       slice));
8175                 }
8176               sscanf(line, "%hd %hd", &(points[2*row]), &(points[2*row+1]));
8177             }
8178         }
8179       else
8180         {
8181           n_read = fread(points, 2, n_rows * 2, fp);
8182           if(n_read != n_rows * 2)
8183             {
8184               free(points);
8185               CMAfreeOutlineField(&of);
8186               errno = 0;
8187               ErrorReturn(ERROR_BADFILE,
8188                           (ERROR_BADFILE,
8189                            "error reading points from otl file %d", slice));
8190             }
8191 #if (BYTE_ORDER == LITTLE_ENDIAN)
8192           swab(points, points, 2 * n_rows * sizeof(short));
8193 #endif
8194         }
8195 
8196       fgets(line, STRLEN, fp);
8197       if(strncmp(line, "END POINTS", 10) != 0)
8198         {
8199           free(points);
8200           CMAfreeOutlineField(&of);
8201           errno = 0;
8202           ErrorReturn
8203             (ERROR_BADFILE,
8204              (ERROR_BADFILE,
8205               "error after points (\"END POINTS\" expected "
8206               "but not found) in otl file %d", slice));
8207         }
8208 
8209       if(!empty_label_flag)
8210         {
8211           strcpy(label_to_compare, label);
8212           for(j = 0;label_to_compare[j] != '\0';j++)
8213             {
8214               if(label_to_compare[j] == '\n')
8215                 label_to_compare[j] = '\0';
8216               if(label_to_compare[j] == ' ')
8217                 label_to_compare[j] = '-';
8218             }
8219 
8220           /* --- strip 'Left' and 'Right'; --- */
8221           strcpy(alt_compare, label_to_compare);
8222           StrLower(alt_compare);
8223           if(strncmp(alt_compare, "left-", 5) == 0)
8224             strcpy(alt_compare, &(label_to_compare[5]));
8225           else if(strncmp(alt_compare, "right-", 6) == 0)
8226             strcpy(alt_compare, &(label_to_compare[6]));
8227 
8228           /* --- strip leading and trailing spaces (now dashes) --- */
8229 
8230           /* leading */
8231           for(j = 0;label_to_compare[j] == '-';j++);
8232           if(label_to_compare[j] != '\0')
8233             {
8234               for(c = label_to_compare;*(c+j) != '\0';c++)
8235                 *c = *(c+j);
8236               *c = *(c+j);
8237             }
8238 
8239           /* trailing */
8240           for(j = strlen(label_to_compare) - 1;
8241               j >= 0 && label_to_compare[j] == '-';
8242               j--);
8243           if(j < 0) /* all dashes! */
8244             {
8245               /* for now, let this fall through to an unknown label */
8246             }
8247           else /* j is the index of the last non-dash character */
8248             {
8249               label_to_compare[j+1] = '\0';
8250             }
8251 
8252 
8253           label_value = -1;
8254           for(j = 0;j < color_table->mnNumEntries;j++)
8255             if(strcmp(color_table->maEntries[j].msLabel,
8256                       label_to_compare) == 0 ||
8257                strcmp(color_table->maEntries[j].msLabel, alt_compare) == 0)
8258               label_value = j;
8259 
8260           if(label_value == -1)
8261             {
8262               register_unknown_label(label);
8263             }
8264           else
8265             {
8266 
8267               for(j = 0;j < n_rows;j++)
8268                 cma_field[points[2*j]][points[2*j+1]] = label_value;
8269 
8270               CMAclaimPoints(of, label_value, points, n_rows, seed_x, seed_y);
8271 
8272             }
8273 
8274         }
8275 
8276       free(points);
8277 
8278     }
8279 
8280   CMAassignLabels(of);
8281 
8282   if(zero_outlines_flag)
8283     CMAzeroOutlines(of);
8284 
8285   scale_x = 512 / mri->width;
8286   scale_y = 512 / mri->height;
8287 
8288   for(i = 0;i < mri->width;i++)
8289     for(j = 0;j < mri->height;j++)
8290       {
8291         source_x = (int)floor(scale_x * (float)i);
8292         source_y = (int)floor(scale_y * (float)j);
8293         if(source_x < 0)
8294           source_x = 0;
8295         if(source_x > 511)
8296           source_x = 511;
8297         if(source_y < 0)
8298           source_y = 0;
8299         if(source_y > 511)
8300           source_y = 511;
8301         MRISvox(mri, i, j, slice-1) = of->fill_field[source_y][source_x];
8302       }
8303 
8304   CMAfreeOutlineField(&of);
8305 
8306   return(NO_ERROR);
8307 
8308 } /* end read_otl_file() */
8309 
8310 MRI *MRIreadOtl
8311 (char *fname, int width, int height, int slices,
8312  char *color_file_name, int flags)
8313 {
8314 
8315   char stem[STRLEN];
8316   int i;
8317   MRI *mri;
8318   char *c;
8319   int one_file_exists;
8320   char first_name[STRLEN], last_name[STRLEN];
8321   FILE *fp;
8322   mriColorLookupTableRef color_table;
8323   int read_volume_flag, fill_flag, translate_labels_flag, zero_outlines_flag;
8324 
8325   /* ----- set local flags ----- */
8326 
8327   read_volume_flag = FALSE;
8328   fill_flag = FALSE;
8329   translate_labels_flag = FALSE;
8330   zero_outlines_flag = FALSE;
8331 
8332   if(flags & READ_OTL_READ_VOLUME_FLAG)
8333     read_volume_flag = TRUE;
8334 
8335   if(flags & READ_OTL_FILL_FLAG)
8336     fill_flag = TRUE;
8337 
8338   if(flags & READ_OTL_TRANSLATE_LABELS_FLAG)
8339     translate_labels_flag = TRUE;
8340 
8341   if(flags & READ_OTL_ZERO_OUTLINES_FLAG)
8342     zero_outlines_flag = TRUE;
8343 
8344   /* ----- reset our unknown label list ----- */
8345 
8346   clear_unknown_labels();
8347 
8348   /* ----- defaults to width and height ----- */
8349   if(width <= 0)
8350     width = 512;
8351   if(height <= 0)
8352     height = 512;
8353 
8354   /* ----- strip the stem of the otl file name ----- */
8355   strcpy(stem, fname);
8356   c = strrchr(stem, '.');
8357   if(c == NULL)
8358     {
8359       errno = 0;
8360       ErrorReturn
8361         (NULL, (ERROR_BADPARM, "MRIreadOtl(): bad file name: %s", fname));
8362     }
8363 
8364   for(c--;c >= stem && isdigit(*c);c--);
8365 
8366   if(c < stem)
8367     {
8368       errno = 0;
8369       ErrorReturn
8370         (NULL, (ERROR_BADPARM, "MRIreadOtl(): bad file name: %s", fname));
8371     }
8372 
8373   c++;
8374 
8375   one_file_exists = FALSE;
8376   for(i = 1;i <= slices;i++)
8377     {
8378       sprintf(c, "%d.otl", i);
8379       if(FileExists(stem))
8380         one_file_exists = TRUE;
8381       if(i == 1)
8382         strcpy(first_name, stem);
8383     }
8384 
8385   strcpy(last_name, stem);
8386 
8387   if(!one_file_exists)
8388     {
8389       errno = 0;
8390       ErrorReturn
8391         (NULL,
8392          (ERROR_BADPARM,
8393           "MRIreadOtl(): couldn't find any file between %s and %s",
8394           first_name, last_name));
8395     }
8396 
8397   if(!read_volume_flag)
8398     {
8399       mri = MRIallocHeader(width, height, slices, MRI_SHORT);
8400       if(mri == NULL)
8401         {
8402           errno = 0;
8403           ErrorReturn
8404             (NULL,
8405              (ERROR_NOMEMORY,
8406               "MRIreadOtl(): error allocating MRI structure"));
8407         }
8408       return(mri);
8409     }
8410   mri = MRIalloc(width, height, slices, MRI_SHORT);
8411   if(mri == NULL)
8412     {
8413       errno = 0;
8414       ErrorReturn
8415         (NULL,
8416          (ERROR_NOMEMORY,
8417           "MRIreadOtl(): error allocating MRI structure"));
8418     }
8419 
8420   if(CLUT_NewFromFile(&color_table, color_file_name) != CLUT_tErr_NoErr)
8421     {
8422       MRIfree(&mri);
8423       errno = 0;
8424       ErrorReturn
8425         (NULL,
8426          (ERROR_BADFILE,
8427           "MRIreadOtl(): error reading color file %s", color_file_name));
8428     }
8429 
8430   one_file_exists = FALSE;
8431   for(i = 1;i <= slices;i++)
8432     {
8433       sprintf(c, "%d.otl", i);
8434       if((fp = fopen(stem, "r")) != NULL)
8435         {
8436           if(read_otl_file
8437              (fp, mri, i, color_table, fill_flag, \
8438               translate_labels_flag, zero_outlines_flag) != NO_ERROR)
8439             {
8440               MRIfree(&mri);
8441               return(NULL);
8442             }
8443           one_file_exists = TRUE;
8444         }
8445     }
8446 
8447   CLUT_Delete(&color_table);
8448 
8449   if(!one_file_exists)
8450     {
8451       MRIfree(&mri);
8452       errno = 0;
8453       ErrorReturn
8454         (NULL,
8455          (ERROR_BADFILE,
8456           "MRIreadOtl(): found at least one file "
8457           "between %s and %s but couldn't open it!", first_name, last_name));
8458     }
8459 
8460   if(n_unknown_labels == 0)
8461     {
8462       printf("no unknown labels\n");
8463     }
8464   else
8465     {
8466       printf("unknown labels:\n");
8467       print_unknown_labels("  ");
8468     }
8469   clear_unknown_labels();
8470 
8471   // default direction cosine set here to be CORONAL
8472   // no orientation info is given and thus set to coronal
8473   setDirectionCosine(mri, MRI_CORONAL);
8474 
8475   return(mri);
8476 
8477 } /* end MRIreadOtl() */
8478 
8479 #define XIMG_PIXEL_DATA_OFFSET    8432
8480 #define XIMG_IMAGE_HEADER_OFFSET  2308
8481 
8482 static MRI *ximgRead(char *fname, int read_volume)
8483 {
8484 
8485   char fname_format[STRLEN];
8486   char fname_dir[STRLEN];
8487   char fname_base[STRLEN];
8488   char *c;
8489   MRI *mri = NULL;
8490   int im_init;
8491   int im_low, im_high;
8492   char fname_use[STRLEN];
8493   char temp_string[STRLEN];
8494   FILE *fp;
8495   int width, height;
8496   int pixel_data_offset;
8497   int image_header_offset;
8498   float tl_r, tl_a, tl_s;
8499   float tr_r, tr_a, tr_s;
8500   float br_r, br_a, br_s;
8501   float c_r, c_a, c_s;
8502   float n_r, n_a, n_s;
8503   float xlength, ylength, zlength;
8504   int i, y;
8505   MRI *header;
8506   float xfov, yfov, zfov;
8507   float nlength;
8508 
8509   printf("XIMG: using XIMG header corrections\n");
8510 
8511   /* ----- check the first (passed) file ----- */
8512   if(!FileExists(fname))
8513     {
8514       errno = 0;
8515       ErrorReturn
8516         (NULL,
8517          (ERROR_BADFILE, "genesisRead(): error opening file %s", fname));
8518     }
8519 
8520   /* ----- split the file name into name and directory ----- */
8521   c = strrchr(fname, '/');
8522   if(c == NULL)
8523     {
8524       fname_dir[0] = '\0';
8525       strcpy(fname_base, fname);
8526     }
8527   else
8528     {
8529       strncpy(fname_dir, fname, (c - fname + 1));
8530       fname_dir[c-fname+1] = '\0';
8531       strcpy(fname_base, c+1);
8532     }
8533 
8534   /* ----- derive the file name format (for sprintf) ----- */
8535   if(strncmp(fname_base, "I.", 2) == 0)
8536     {
8537       im_init = atoi(&fname_base[2]);
8538       sprintf(fname_format, "I.%%03d");
8539     }
8540   else if(strlen(fname_base) >= 3) /* avoid core dumps below... */
8541     {
8542       c = &fname_base[strlen(fname_base)-3];
8543       if(strcmp(c, ".MR") == 0)
8544         {
8545           *c = '\0';
8546           for(c--;isdigit(*c) && c >= fname_base;c--);
8547           c++;
8548           im_init = atoi(c);
8549           *c = '\0';
8550           sprintf(fname_format, "%s%%d.MR", fname_base);
8551         }
8552       else
8553         {
8554           errno = 0;
8555           ErrorReturn
8556             (NULL,
8557              (ERROR_BADPARM,
8558               "genesisRead(): can't determine file name format for %s",
8559               fname));
8560         }
8561     }
8562   else
8563     {
8564       errno = 0;
8565       ErrorReturn
8566         (NULL,
8567          (ERROR_BADPARM,
8568           "genesisRead(): can't determine file name format for %s", fname));
8569     }
8570 
8571   strcpy(temp_string, fname_format);
8572   sprintf(fname_format, "%s%s", fname_dir, temp_string);
8573 
8574   /* ----- find the low and high files ----- */
8575   im_low = im_init;
8576   do
8577     {
8578       im_low--;
8579       sprintf(fname_use, fname_format, im_low);
8580     } while(FileExists(fname_use));
8581   im_low++;
8582 
8583   im_high = im_init;
8584   do
8585     {
8586       im_high++;
8587       sprintf(fname_use, fname_format, im_high);
8588     } while(FileExists(fname_use));
8589   im_high--;
8590 
8591   /* ----- allocate the mri structure ----- */
8592   header = MRIallocHeader(1, 1, 1, MRI_SHORT);
8593 
8594   header->depth = im_high - im_low + 1;
8595   header->imnr0 = 1;
8596   header->imnr1 = header->depth;
8597 
8598   /* ----- get the header information from the first file ----- */
8599   sprintf(fname_use, fname_format, im_low);
8600   if((fp = fopen(fname_use, "r")) == NULL)
8601     {
8602       MRIfree(&header);
8603       errno = 0;
8604       ErrorReturn
8605         (NULL,
8606          (ERROR_BADFILE, "genesisRead(): error opening file %s\n", fname_use));
8607     }
8608 
8609   fseek(fp, 4, SEEK_SET);
8610   fread(&pixel_data_offset, 4, 1, fp);
8611   pixel_data_offset = orderIntBytes(pixel_data_offset);
8612   printf("XIMG: pixel data offset is %d, ", pixel_data_offset);
8613   if(pixel_data_offset != XIMG_PIXEL_DATA_OFFSET)
8614     pixel_data_offset = XIMG_PIXEL_DATA_OFFSET;
8615   printf("using offset %d\n", pixel_data_offset);
8616 
8617   fseek(fp, 8, SEEK_SET);
8618   fread(&width, 4, 1, fp);  width = orderIntBytes(width);
8619   fread(&height, 4, 1, fp);  height = orderIntBytes(height);
8620 
8621   fseek(fp, 148, SEEK_SET);
8622   fread(&image_header_offset, 4, 1, fp);
8623   image_header_offset = orderIntBytes(image_header_offset);
8624   printf("XIMG: image header offset is %d, ", image_header_offset);
8625   if(image_header_offset != XIMG_IMAGE_HEADER_OFFSET)
8626     image_header_offset = XIMG_IMAGE_HEADER_OFFSET;
8627   printf("using offset %d\n", image_header_offset);
8628 
8629   header->width = width;
8630   header->height = height;
8631 
8632   strcpy(header->fname, fname);
8633 
8634   fseek(fp, image_header_offset + 26 + 2, SEEK_SET);
8635   fread(&(header->thick), 4, 1, fp);
8636   header->thick = orderFloatBytes(header->thick);
8637   header->zsize = header->thick;
8638 
8639   fseek(fp, image_header_offset + 50 + 2, SEEK_SET);
8640   fread(&(header->xsize), 4, 1, fp);
8641   header->xsize = orderFloatBytes(header->xsize);
8642   fread(&(header->ysize), 4, 1, fp);
8643   header->ysize = orderFloatBytes(header->ysize);
8644   header->ps = header->xsize;
8645 
8646   /* all in micro-seconds */
8647 #define MICROSECONDS_PER_MILLISECOND 1e3
8648   fseek(fp, image_header_offset + 194 + 6, SEEK_SET);
8649   header->tr = freadInt(fp)/MICROSECONDS_PER_MILLISECOND ;
8650   fseek(fp, image_header_offset + 198, SEEK_SET);
8651   header->ti = freadInt(fp)/MICROSECONDS_PER_MILLISECOND  ;
8652   fseek(fp, image_header_offset + 202, SEEK_SET);
8653   header->te = freadInt(fp)/MICROSECONDS_PER_MILLISECOND  ;
8654   fseek(fp, image_header_offset + 254, SEEK_SET);
8655   header->flip_angle = RADIANS(freadShort(fp)) ;  /* was in degrees */
8656 
8657   fseek(fp, image_header_offset + 130 + 6, SEEK_SET);
8658   fread(&c_r,  4, 1, fp);  c_r  = orderFloatBytes(c_r);
8659   fread(&c_a,  4, 1, fp);  c_a  = orderFloatBytes(c_a);
8660   fread(&c_s,  4, 1, fp);  c_s  = orderFloatBytes(c_s);
8661   fread(&n_r,  4, 1, fp);  n_r  = orderFloatBytes(n_r);
8662   fread(&n_a,  4, 1, fp);  n_a  = orderFloatBytes(n_a);
8663   fread(&n_s,  4, 1, fp);  n_s  = orderFloatBytes(n_s);
8664   fread(&tl_r, 4, 1, fp);  tl_r = orderFloatBytes(tl_r);
8665   fread(&tl_a, 4, 1, fp);  tl_a = orderFloatBytes(tl_a);
8666   fread(&tl_s, 4, 1, fp);  tl_s = orderFloatBytes(tl_s);
8667   fread(&tr_r, 4, 1, fp);  tr_r = orderFloatBytes(tr_r);
8668   fread(&tr_a, 4, 1, fp);  tr_a = orderFloatBytes(tr_a);
8669   fread(&tr_s, 4, 1, fp);  tr_s = orderFloatBytes(tr_s);
8670   fread(&br_r, 4, 1, fp);  br_r = orderFloatBytes(br_r);
8671   fread(&br_a, 4, 1, fp);  br_a = orderFloatBytes(br_a);
8672   fread(&br_s, 4, 1, fp);  br_s = orderFloatBytes(br_s);
8673 
8674   nlength = sqrt(n_r*n_r + n_a*n_a + n_s*n_s);
8675   n_r = n_r / nlength;
8676   n_a = n_a / nlength;
8677   n_s = n_s / nlength;
8678 
8679   if (getenv("KILLIANY_SWAP") != NULL)
8680     {
8681       printf("WARNING - swapping normal direction!\n") ;
8682       n_a *= -1 ;
8683     }
8684 
8685   header->x_r = (tr_r - tl_r);
8686   header->x_a = (tr_a - tl_a);
8687   header->x_s = (tr_s - tl_s);
8688   header->y_r = (br_r - tr_r);
8689   header->y_a = (br_a - tr_a);
8690   header->y_s = (br_s - tr_s);
8691 
8692   /* --- normalize -- the normal vector from the file
8693      should have length 1, but just in case... --- */
8694   xlength = sqrt(header->x_r*header->x_r +
8695                  header->x_a*header->x_a +
8696                  header->x_s*header->x_s);
8697   ylength = sqrt(header->y_r*header->y_r +
8698                  header->y_a*header->y_a +
8699                  header->y_s*header->y_s);
8700   zlength = sqrt(n_r*n_r + n_a*n_a + n_s*n_s);
8701 
8702   header->x_r = header->x_r / xlength;
8703   header->x_a = header->x_a / xlength;
8704   header->x_s = header->x_s / xlength;
8705   header->y_r = header->y_r / ylength;
8706   header->y_a = header->y_a / ylength;
8707   header->y_s = header->y_s / ylength;
8708   header->z_r = n_r / zlength;
8709   header->z_a = n_a / zlength;
8710   header->z_s = n_s / zlength;
8711 
8712   header->c_r = (tl_r + br_r) / 2.0 + n_r * header->zsize *
8713     (header->depth - 1.0) / 2.0;
8714   header->c_a = (tl_a + br_a) / 2.0 + n_a * header->zsize *
8715     (header->depth - 1.0) / 2.0;
8716   header->c_s = (tl_s + br_s) / 2.0 + n_s * header->zsize *
8717     (header->depth - 1.0) / 2.0;
8718 
8719   header->ras_good_flag = 1;
8720 
8721   header->xend = header->xsize * header->width / 2;
8722   header->xstart = -header->xend;
8723   header->yend = header->ysize * header->height / 2;
8724   header->ystart = -header->yend;
8725   header->zend = header->zsize * header->depth / 2;
8726   header->zstart = -header->zend;
8727 
8728   xfov = header->xend - header->xstart;
8729   yfov = header->yend - header->ystart;
8730   zfov = header->zend - header->zstart;
8731 
8732   header->fov =
8733     (xfov > yfov ? (xfov > zfov ? xfov : zfov) : (yfov > zfov ? yfov : zfov));
8734 
8735   fclose(fp);
8736 
8737   if(read_volume)
8738     mri = MRIalloc
8739       (header->width, header->height, header->depth, header->type);
8740   else
8741     mri = MRIallocHeader
8742       (header->width, header->height, header->depth, header->type);
8743 
8744   MRIcopyHeader(header, mri);
8745   MRIfree(&header);
8746 
8747   /* ----- read the volume if required ----- */
8748   if(read_volume)
8749     {
8750 
8751       for(i = im_low;i <= im_high;i++)
8752         {
8753 
8754           sprintf(fname_use, fname_format, i);
8755           if((fp = fopen(fname_use, "r")) == NULL)
8756             {
8757               MRIfree(&mri);
8758               errno = 0;
8759               ErrorReturn
8760                 (NULL,
8761                  (ERROR_BADFILE,
8762                   "genesisRead(): error opening file %s", fname_use));
8763             }
8764 
8765           /*
8766             fseek(fp, 4, SEEK_SET);
8767             fread(&pixel_data_offset, 4, 1, fp);
8768             pixel_data_offset = orderIntBytes(pixel_data_offset);
8769           */
8770           pixel_data_offset = XIMG_PIXEL_DATA_OFFSET;
8771           fseek(fp, pixel_data_offset, SEEK_SET);
8772 
8773           for(y = 0;y < mri->height;y++)
8774             {
8775               if(fread(mri->slices[i-im_low][y], 2, mri->width, fp) !=
8776                  mri->width)
8777                 {
8778                   fclose(fp);
8779                   MRIfree(&mri);
8780                   errno = 0;
8781                   ErrorReturn
8782                     (NULL,
8783                      (ERROR_BADFILE,
8784                       "genesisRead(): error reading from file file %s",
8785                       fname_use));
8786                 }
8787 #if (BYTE_ORDER == LITTLE_ENDIAN)
8788               swab(mri->slices[i-im_low][y],
8789                    mri->slices[i-im_low][y], 2 * mri->width);
8790 #endif
8791             }
8792 
8793           fclose(fp);
8794 
8795         }
8796 
8797     }
8798 
8799   return(mri);
8800 
8801 } /* end ximgRead() */
8802 
8803 /*-----------------------------------------------------------
8804   MRISreadCurvAsMRI() - reads freesurfer surface curv format
8805   as an MRI.
8806   -----------------------------------------------------------*/
8807 static MRI *MRISreadCurvAsMRI(char *curvfile, int read_volume)
8808 {
8809   int    magno,k,vnum,fnum, vals_per_vertex ;
8810   float  curv;
8811   FILE   *fp;
8812   MRI *curvmri;
8813 
8814   if(!IDisCurv(curvfile)) return(NULL);
8815 
8816   fp = fopen(curvfile,"r");
8817   fread3(&magno,fp);
8818 
8819   vnum = freadInt(fp);
8820   fnum = freadInt(fp);
8821   vals_per_vertex = freadInt(fp) ;
8822   if (vals_per_vertex != 1){
8823     fclose(fp) ;
8824     printf("ERROR: MRISreadCurvAsMRI: %s, vals/vertex %d unsupported\n",
8825            curvfile,vals_per_vertex);
8826     return(NULL);
8827   }
8828 
8829   if(!read_volume){
8830     curvmri = MRIallocHeader(vnum, 1,1,MRI_FLOAT);
8831     curvmri->nframes = 1;
8832     return(curvmri);
8833   }
8834 
8835   curvmri = MRIalloc(vnum,1,1,MRI_FLOAT);
8836   for (k=0;k<vnum;k++){
8837     curv = freadFloat(fp) ;
8838     MRIsetVoxVal(curvmri,k,0,0,0,curv);
8839   }
8840   fclose(fp);
8841 
8842   return(curvmri) ;
8843 }
8844 
8845 /*------------------------------------------------------------------
8846   nifti1Read() - note: there is also an niiRead(). Make sure to
8847   edit both. NIFTI1 is defined to be the two-file NIFTI standard, ie,
8848   there must be a .img and .hdr file. (see is_nifti1(char *fname))
8849   -----------------------------------------------------------------*/
8850 static MRI *nifti1Read(char *fname, int read_volume)
8851 {
8852 
8853   char hdr_fname[STRLEN];
8854   char img_fname[STRLEN];
8855   char fname_stem[STRLEN];
8856   char *dot;
8857   FILE *fp;
8858   MRI *mri;
8859   struct nifti_1_header hdr;
8860   int nslices;
8861   int fs_type;
8862   float time_units_factor, space_units_factor;
8863   int swapped_flag;
8864   int n_read, i, j, k, t;
8865   int bytes_per_voxel, time_units, space_units;
8866 
8867   strcpy(fname_stem, fname);
8868   dot = strrchr(fname_stem, '.');
8869   if(dot != NULL)
8870     if(strcmp(dot, ".img") == 0 || strcmp(dot, ".hdr") == 0)
8871       *dot = '\0';
8872 
8873   sprintf(hdr_fname, "%s.hdr", fname_stem);
8874   sprintf(img_fname, "%s.img", fname_stem);
8875 
8876   fp = fopen(hdr_fname, "r");
8877   if(fp == NULL)
8878     {
8879       errno = 0;
8880       ErrorReturn
8881         (NULL,
8882          (ERROR_BADFILE, "nifti1Read(): error opening file %s", hdr_fname));
8883     }
8884 
8885   if(fread(&hdr, sizeof(hdr), 1, fp) != 1)
8886     {
8887       fclose(fp);
8888       errno = 0;
8889       ErrorReturn
8890         (NULL,
8891          (ERROR_BADFILE,
8892           "nifti1Read(): error reading header from %s", hdr_fname));
8893     }
8894 
8895   fclose(fp);
8896 
8897   swapped_flag = FALSE;
8898   if(hdr.dim[0] < 1 || hdr.dim[0] > 7){
8899     swapped_flag = TRUE;
8900     swap_nifti_1_header(&hdr);
8901     if(hdr.dim[0] < 1 || hdr.dim[0] > 7){
8902       ErrorReturn
8903         (NULL,
8904          (ERROR_BADFILE,
8905           "nifti1Read(): bad number of dimensions (%hd) in %s",
8906           hdr.dim[0], hdr_fname));
8907     }
8908   }
8909 
8910   if(memcmp(hdr.magic, NIFTI1_MAGIC, 4) != 0)
8911     ErrorReturn
8912       (NULL,
8913        (ERROR_BADFILE,
8914         "nifti1Read(): bad magic number in %s", hdr_fname));
8915 
8916   if(hdr.dim[0] != 3 && hdr.dim[0] != 4)
8917     ErrorReturn
8918       (NULL,
8919        (ERROR_UNSUPPORTED,
8920         "nifti1Read(): %hd dimensions in %s; unsupported",
8921         hdr.dim[0], hdr_fname));
8922 
8923   if(hdr.datatype == DT_NONE || hdr.datatype == DT_UNKNOWN)
8924     ErrorReturn
8925       (NULL,
8926        (ERROR_UNSUPPORTED,
8927         "nifti1Read(): unknown or no data type in %s; bailing out",
8928         hdr_fname));
8929 
8930   space_units  = XYZT_TO_SPACE(hdr.xyzt_units) ;
8931   if(space_units ==NIFTI_UNITS_METER)       space_units_factor = 1000.0;
8932   else if(space_units ==NIFTI_UNITS_MM)     space_units_factor = 1.0;
8933   else if(space_units ==NIFTI_UNITS_MICRON) space_units_factor = 0.001;
8934   else
8935     {
8936       ErrorReturn
8937         (NULL,
8938          (ERROR_BADFILE,
8939           "nifti1Read(): unknown space units %d in %s",
8940           space_units,hdr_fname));
8941     }
8942 
8943   time_units = XYZT_TO_TIME (hdr.xyzt_units) ;
8944   if(time_units == NIFTI_UNITS_SEC)       time_units_factor = 1000.0;
8945   else if(time_units == NIFTI_UNITS_MSEC) time_units_factor = 1.0;
8946   else if(time_units == NIFTI_UNITS_USEC) time_units_factor = 0.001;
8947   else {
8948     if(hdr.dim[4] > 1){
8949       ErrorReturn
8950         (NULL,
8951          (ERROR_BADFILE,
8952           "nifti1Read(): unknown time units %d in %s",
8953           time_units,hdr_fname));
8954     }
8955     else time_units_factor = 0;
8956   }
8957 
8958   /*
8959     nifti1.h says: slice_code = If this is nonzero, AND
8960     if slice_dim is nonzero, AND
8961     if slice_duration is positive, indicates the timing
8962     pattern of the slice acquisition.
8963     not yet supported here
8964   */
8965 
8966   if(hdr.slice_code != 0 &&
8967      DIM_INFO_TO_SLICE_DIM(hdr.dim_info) != 0 &&
8968      hdr.slice_duration > 0.0)
8969     ErrorReturn
8970       (NULL,
8971        (ERROR_UNSUPPORTED,
8972         "nifti1Read(): unsupported timing pattern in %s", hdr_fname));
8973 
8974   if(hdr.dim[0] == 3) nslices = 1;
8975   else                nslices = hdr.dim[4];
8976 
8977   if(hdr.scl_slope == 0)
8978     // voxel values are unscaled -- we use the file's data type
8979     {
8980 
8981       if(hdr.datatype == DT_UNSIGNED_CHAR)
8982         {
8983           fs_type = MRI_UCHAR;
8984           bytes_per_voxel = 1;
8985         }
8986       else if(hdr.datatype == DT_SIGNED_SHORT)
8987         {
8988           fs_type = MRI_SHORT;
8989           bytes_per_voxel = 2;
8990         }
8991       else if(hdr.datatype == DT_SIGNED_INT)
8992         {
8993           fs_type = MRI_INT;
8994           bytes_per_voxel = 4;
8995         }
8996       else if(hdr.datatype == DT_FLOAT)
8997         {
8998           fs_type = MRI_FLOAT;
8999           bytes_per_voxel = 4;
9000         }
9001       else
9002         {
9003           ErrorReturn
9004             (NULL,
9005              (ERROR_UNSUPPORTED,
9006               "nifti1Read(): unsupported datatype %d "
9007               "(with scl_slope = 0) in %s",
9008               hdr.datatype, hdr_fname));
9009         }
9010     }
9011   else // we must scale the voxel values
9012     {
9013       if(   hdr.datatype != DT_UNSIGNED_CHAR
9014             && hdr.datatype != DT_SIGNED_SHORT
9015             && hdr.datatype != DT_SIGNED_INT
9016             && hdr.datatype != DT_FLOAT
9017             && hdr.datatype != DT_DOUBLE
9018             && hdr.datatype != DT_INT8
9019             && hdr.datatype != DT_UINT16
9020             && hdr.datatype != DT_UINT32)
9021         {
9022           ErrorReturn
9023             (NULL,
9024              (ERROR_UNSUPPORTED,
9025               "nifti1Read(): unsupported datatype %d "
9026               "(with scl_slope != 0) in %s",
9027               hdr.datatype, hdr_fname));
9028         }
9029       fs_type = MRI_FLOAT;
9030       bytes_per_voxel = 0; /* set below -- this line is to
9031                               avoid the compiler warning */
9032     }
9033 
9034   if(read_volume)
9035     mri = MRIallocSequence
9036       (hdr.dim[1], hdr.dim[2], hdr.dim[3], fs_type, nslices);
9037   else
9038     {
9039       mri = MRIallocHeader(hdr.dim[1], hdr.dim[2], hdr.dim[3], fs_type);
9040       mri->nframes = nslices;
9041     }
9042 
9043   if(mri == NULL)
9044     return(NULL);
9045 
9046   mri->xsize = hdr.pixdim[1];
9047   mri->ysize = hdr.pixdim[2];
9048   mri->zsize = hdr.pixdim[3];
9049   // Keep in msec as NIFTI_UNITS_MSEC is specified
9050   if(hdr.dim[0] == 4) mri->tr = hdr.pixdim[4];
9051 
9052   if(hdr.qform_code == 0){
9053     printf("WARNING: missing NIfTI-1 orientation (qform_code = 0)\n");
9054     printf("WARNING: your volume will probably be incorrectly oriented\n");
9055     mri->x_r = 1.0;  mri->x_a = 0.0;  mri->x_s = 0.0;
9056     mri->y_r = 0.0;  mri->y_a = 1.0;  mri->y_s = 0.0;
9057     mri->z_r = 0.0;  mri->z_a = 0.0;  mri->z_s = 1.0;
9058     mri->c_r = mri->xsize * mri->width / 2.0;
9059     mri->c_a = mri->ysize * mri->height / 2.0;
9060     mri->c_s = mri->zsize * mri->depth / 2.0;
9061   }
9062   else if(hdr.sform_code <= 0){
9063     if(niftiQformToMri(mri, &hdr) != NO_ERROR){
9064       MRIfree(&mri);
9065       return(NULL);
9066     }
9067   }
9068   else{
9069     if(niftiSformToMri(mri, &hdr) != NO_ERROR){
9070       MRIfree(&mri);
9071       return(NULL);
9072     }
9073   }
9074 
9075   mri->xsize = mri->xsize * space_units_factor;
9076   mri->ysize = mri->ysize * space_units_factor;
9077   mri->zsize = mri->zsize * space_units_factor;
9078   mri->c_r = mri->c_r * space_units_factor;
9079   mri->c_a = mri->c_a * space_units_factor;
9080   mri->c_s = mri->c_s * space_units_factor;
9081   if(hdr.dim[0] == 4)
9082     mri->tr = mri->tr * time_units_factor;
9083 
9084   if(!read_volume)
9085     return(mri);
9086 
9087   fp = fopen(img_fname, "r");
9088   if(fp == NULL){
9089     MRIfree(&mri);
9090     errno = 0;
9091     ErrorReturn
9092       (NULL,
9093        (ERROR_BADFILE, "nifti1Read(): error opening file %s", img_fname));
9094   }
9095 
9096   if(hdr.scl_slope == 0) // no voxel value scaling needed
9097     {
9098 
9099       void *buf;
9100 
9101       for(t = 0;t < mri->nframes;t++)
9102         for(k = 0;k < mri->depth;k++)
9103           for(j = 0;j < mri->height;j++)
9104             {
9105 
9106               buf = &MRIseq_vox(mri, 0, j, k, t);
9107 
9108               n_read = fread(buf, bytes_per_voxel, mri->width, fp);
9109               if(n_read != mri->width)
9110                 {
9111                   fclose(fp);
9112                   MRIfree(&mri);
9113                   errno = 0;
9114                   ErrorReturn
9115                     (NULL,
9116                      (ERROR_BADFILE,
9117                       "nifti1Read(): error reading from %s", img_fname));
9118                 }
9119 
9120               if(swapped_flag)
9121                 {
9122                   if(bytes_per_voxel == 2)
9123                     byteswapbufshort(buf, bytes_per_voxel * mri->width);
9124                   if(bytes_per_voxel == 4)
9125                     byteswapbuffloat(buf, bytes_per_voxel * mri->width);
9126                 }
9127 
9128             }
9129 
9130     }
9131   else // voxel value scaling needed
9132     {
9133 
9134       if(hdr.datatype == DT_UNSIGNED_CHAR)
9135         {
9136           unsigned char *buf;
9137           bytes_per_voxel = 1;
9138           buf = (unsigned char *)malloc(mri->width * bytes_per_voxel);
9139           for(t = 0;t < mri->nframes;t++)
9140             for(k = 0;k < mri->depth;k++)
9141               for(j = 0;j < mri->height;j++)
9142                 {
9143                   n_read = fread(buf, bytes_per_voxel, mri->width, fp);
9144                   if(n_read != mri->width)
9145                     {
9146                       free(buf);
9147                       fclose(fp);
9148                       MRIfree(&mri);
9149                       errno = 0;
9150                       ErrorReturn
9151                         (NULL,
9152                          (ERROR_BADFILE,
9153                           "nifti1Read(): error reading from %s", img_fname));
9154                     }
9155                   for(i = 0;i < mri->width;i++)
9156                     MRIFseq_vox(mri, i, j, k, t) =
9157                       hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
9158                 }
9159           free(buf);
9160         }
9161 
9162       if(hdr.datatype == DT_SIGNED_SHORT)
9163         {
9164           short *buf;
9165           bytes_per_voxel = 2;
9166           buf = (short *)malloc(mri->width * bytes_per_voxel);
9167           for(t = 0;t < mri->nframes;t++)
9168             for(k = 0;k < mri->depth;k++)
9169               for(j = 0;j < mri->height;j++)
9170                 {
9171                   n_read = fread(buf, bytes_per_voxel, mri->width, fp);
9172                   if(n_read != mri->width)
9173                     {
9174                       free(buf);
9175                       fclose(fp);
9176                       MRIfree(&mri);
9177                       errno = 0;
9178                       ErrorReturn
9179                         (NULL,
9180                          (ERROR_BADFILE,
9181                           "nifti1Read(): error reading from %s", img_fname));
9182                     }
9183                   if(swapped_flag)
9184                     byteswapbufshort(buf, bytes_per_voxel * mri->width);
9185                   for(i = 0;i < mri->width;i++)
9186                     MRIFseq_vox(mri, i, j, k, t) =
9187                       hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
9188                 }
9189           free(buf);
9190         }
9191 
9192       if(hdr.datatype == DT_SIGNED_INT)
9193         {
9194           int *buf;
9195           bytes_per_voxel = 4;
9196           buf = (int *)malloc(mri->width * bytes_per_voxel);
9197           for(t = 0;t < mri->nframes;t++)
9198             for(k = 0;k < mri->depth;k++)
9199               for(j = 0;j < mri->height;j++)
9200                 {
9201                   n_read = fread(buf, bytes_per_voxel, mri->width, fp);
9202                   if(n_read != mri->width)
9203                     {
9204                       free(buf);
9205                       fclose(fp);
9206                       MRIfree(&mri);
9207                       errno = 0;
9208                       ErrorReturn
9209                         (NULL,
9210                          (ERROR_BADFILE,
9211                           "nifti1Read(): error reading from %s", img_fname));
9212                     }
9213                   if(swapped_flag)
9214                     byteswapbuffloat(buf, bytes_per_voxel * mri->width);
9215                   for(i = 0;i < mri->width;i++)
9216                     MRIFseq_vox(mri, i, j, k, t) =
9217                       hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
9218                 }
9219           free(buf);
9220         }
9221 
9222       if(hdr.datatype == DT_FLOAT)
9223         {
9224           float *buf;
9225           bytes_per_voxel = 4;
9226           buf = (float *)malloc(mri->width * bytes_per_voxel);
9227           for(t = 0;t < mri->nframes;t++)
9228             for(k = 0;k < mri->depth;k++)
9229               for(j = 0;j < mri->height;j++)
9230                 {
9231                   n_read = fread(buf, bytes_per_voxel, mri->width, fp);
9232                   if(n_read != mri->width)
9233                     {
9234                       free(buf);
9235                       fclose(fp);
9236                       MRIfree(&mri);
9237                       errno = 0;
9238                       ErrorReturn
9239                         (NULL,
9240                          (ERROR_BADFILE,
9241                           "nifti1Read(): error reading from %s", img_fname));
9242                     }
9243                   if(swapped_flag)
9244                     byteswapbuffloat(buf, bytes_per_voxel * mri->width);
9245                   for(i = 0;i < mri->width;i++)
9246                     MRIFseq_vox(mri, i, j, k, t) =
9247                       hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
9248                 }
9249           free(buf);
9250         }
9251 
9252       if(hdr.datatype == DT_DOUBLE)
9253         {
9254           double *buf;
9255           unsigned char *cbuf, ccbuf[8];
9256           bytes_per_voxel = 8;
9257           buf = (double *)malloc(mri->width * bytes_per_voxel);
9258           for(t = 0;t < mri->nframes;t++)
9259             for(k = 0;k < mri->depth;k++)
9260               for(j = 0;j < mri->height;j++)
9261                 {
9262                   n_read = fread(buf, bytes_per_voxel, mri->width, fp);
9263                   if(n_read != mri->width)
9264                     {
9265                       free(buf);
9266                       fclose(fp);
9267                       MRIfree(&mri);
9268                       errno = 0;
9269                       ErrorReturn
9270                         (NULL,
9271                          (ERROR_BADFILE,
9272                           "nifti1Read(): error reading from %s", img_fname));
9273                     }
9274                   if(swapped_flag)
9275                     {
9276                       for(i = 0;i < mri->width;i++)
9277                         {
9278                           cbuf = (unsigned char *)&buf[i];
9279                           memcpy(ccbuf, cbuf, 8);
9280                           cbuf[0] = ccbuf[7];
9281                           cbuf[1] = ccbuf[6];
9282                           cbuf[2] = ccbuf[5];
9283                           cbuf[3] = ccbuf[4];
9284                           cbuf[4] = ccbuf[3];
9285                           cbuf[5] = ccbuf[2];
9286                           cbuf[6] = ccbuf[1];
9287                           cbuf[7] = ccbuf[0];
9288                         }
9289                     }
9290                   for(i = 0;i < mri->width;i++)
9291                     MRIFseq_vox(mri, i, j, k, t) =
9292                       hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
9293                 }
9294           free(buf);
9295         }
9296 
9297       if(hdr.datatype == DT_INT8)
9298         {
9299           char *buf;
9300           bytes_per_voxel = 1;
9301           buf = (char *)malloc(mri->width * bytes_per_voxel);
9302           for(t = 0;t < mri->nframes;t++)
9303             for(k = 0;k < mri->depth;k++)
9304               for(j = 0;j < mri->height;j++)
9305                 {
9306                   n_read = fread(buf, bytes_per_voxel, mri->width, fp);
9307                   if(n_read != mri->width)
9308                     {
9309                       free(buf);
9310                       fclose(fp);
9311                       MRIfree(&mri);
9312                       errno = 0;
9313                       ErrorReturn
9314                         (NULL,
9315                          (ERROR_BADFILE,
9316                           "nifti1Read(): error reading from %s",
9317                           img_fname));
9318                     }
9319                   for(i = 0;i < mri->width;i++)
9320                     MRIFseq_vox(mri, i, j, k, t) =
9321                       hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
9322                 }
9323           free(buf);
9324         }
9325 
9326       if(hdr.datatype == DT_UINT16)
9327         {
9328           unsigned short *buf;
9329           bytes_per_voxel = 2;
9330           buf = (unsigned short *)malloc(mri->width * bytes_per_voxel);
9331           for(t = 0;t < mri->nframes;t++)
9332             for(k = 0;k < mri->depth;k++)
9333               for(j = 0;j < mri->height;j++)
9334                 {
9335                   n_read = fread(buf, bytes_per_voxel, mri->width, fp);
9336                   if(n_read != mri->width)
9337                     {
9338                       free(buf);
9339                       fclose(fp);
9340                       MRIfree(&mri);
9341                       errno = 0;
9342                       ErrorReturn
9343                         (NULL,
9344                          (ERROR_BADFILE,
9345                           "nifti1Read(): error reading from %s",
9346                           img_fname));
9347                     }
9348                   if(swapped_flag)
9349                     byteswapbufshort(buf, bytes_per_voxel * mri->width);
9350                   for(i = 0;i < mri->width;i++)
9351                     MRIFseq_vox(mri, i, j, k, t) =
9352                       hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
9353                 }
9354           free(buf);
9355         }
9356 
9357       if(hdr.datatype == DT_UINT32)
9358         {
9359           unsigned int *buf;
9360           bytes_per_voxel = 4;
9361           buf = (unsigned int *)malloc(mri->width * bytes_per_voxel);
9362           for(t = 0;t < mri->nframes;t++)
9363             for(k = 0;k < mri->depth;k++)
9364               for(j = 0;j < mri->height;j++)
9365                 {
9366                   n_read = fread(buf, bytes_per_voxel, mri->width, fp);
9367                   if(n_read != mri->width)
9368                     {
9369                       free(buf);
9370                       fclose(fp);
9371                       MRIfree(&mri);
9372                       errno = 0;
9373                       ErrorReturn
9374                         (NULL,
9375                          (ERROR_BADFILE,
9376                           "nifti1Read(): error reading from %s",
9377                           img_fname));
9378                     }
9379                   if(swapped_flag)
9380                     byteswapbuffloat(buf, bytes_per_voxel * mri->width);
9381                   for(i = 0;i < mri->width;i++)
9382                     MRIFseq_vox(mri, i, j, k, t) =
9383                       hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
9384                 }
9385           free(buf);
9386         }
9387 
9388     }
9389 
9390   fclose(fp);
9391 
9392   return(mri);
9393 
9394 } /* end nifti1Read() */
9395 
9396 
9397 /*------------------------------------------------------------------
9398   nifti1Write() - note: there is also an niiWrite(). Make sure to
9399   edit both.
9400   -----------------------------------------------------------------*/
9401 static int nifti1Write(MRI *mri, char *fname)
9402 {
9403 
9404   FILE *fp;
9405   int j, k, t;
9406   BUFTYPE *buf;
9407   struct nifti_1_header hdr;
9408   char fname_stem[STRLEN];
9409   char hdr_fname[STRLEN];
9410   char img_fname[STRLEN];
9411   char *dot;
9412   int error;
9413 
9414   memset(&hdr, 0x00, sizeof(hdr));
9415 
9416   hdr.sizeof_hdr = 348;
9417   hdr.dim_info = 0;
9418 
9419   if(mri->nframes == 1){
9420     hdr.dim[0] = 3;
9421     hdr.dim[1] = mri->width;
9422     hdr.dim[2] = mri->height;
9423     hdr.dim[3] = mri->depth;
9424     hdr.pixdim[1] = mri->xsize;
9425     hdr.pixdim[2] = mri->ysize;
9426     hdr.pixdim[3] = mri->zsize;
9427   }
9428   else{
9429     hdr.dim[0] = 4;
9430     hdr.dim[1] = mri->width;
9431     hdr.dim[2] = mri->height;
9432     hdr.dim[3] = mri->depth;
9433     hdr.dim[4] = mri->nframes;
9434     hdr.pixdim[1] = mri->xsize;
9435     hdr.pixdim[2] = mri->ysize;
9436     hdr.pixdim[3] = mri->zsize;
9437     hdr.pixdim[4] = mri->tr/1000.0; // sec, see also xyzt_units
9438   }
9439 
9440   if(mri->type == MRI_UCHAR){
9441     hdr.datatype = DT_UNSIGNED_CHAR;
9442     hdr.bitpix = 8;
9443   }
9444   else if(mri->type == MRI_INT)
9445     {
9446       hdr.datatype = DT_SIGNED_INT;
9447       hdr.bitpix = 32;
9448     }
9449   else if(mri->type == MRI_LONG)
9450     {
9451       hdr.datatype = DT_SIGNED_INT;
9452       hdr.bitpix = 32;
9453     }
9454   else if(mri->type == MRI_FLOAT)
9455     {
9456       hdr.datatype = DT_FLOAT;
9457       hdr.bitpix = 32;
9458     }
9459   else if(mri->type == MRI_SHORT)
9460     {
9461       hdr.datatype = DT_SIGNED_SHORT;
9462       hdr.bitpix = 16;
9463     }
9464   else if(mri->type == MRI_BITMAP)
9465     {
9466       ErrorReturn(ERROR_UNSUPPORTED,
9467                   (ERROR_UNSUPPORTED,
9468                    "nifti1Write(): data type MRI_BITMAP unsupported"));
9469     }
9470   else if(mri->type == MRI_TENSOR)
9471     {
9472       ErrorReturn(ERROR_UNSUPPORTED,
9473                   (ERROR_UNSUPPORTED,
9474                    "nifti1Write(): data type MRI_TENSOR unsupported"));
9475     }
9476   else
9477     {
9478       ErrorReturn(ERROR_BADPARM,
9479                   (ERROR_BADPARM,
9480                    "nifti1Write(): unknown data type %d", mri->type));
9481     }
9482 
9483   hdr.intent_code = NIFTI_INTENT_NONE;
9484   hdr.intent_name[0] = '\0';
9485   hdr.vox_offset = 0;
9486   hdr.scl_slope = 0.0;
9487   hdr.slice_code = 0;
9488   hdr.xyzt_units = NIFTI_UNITS_MM | NIFTI_UNITS_SEC; // This may be wrong
9489   hdr.cal_max = 0.0;
9490   hdr.cal_min = 0.0;
9491   hdr.toffset = 0;
9492 
9493   /* set the nifti header qform values */
9494   error = mriToNiftiQform(mri, &hdr);
9495   if(error != NO_ERROR) return(error);
9496 
9497   memcpy(hdr.magic, NIFTI1_MAGIC, 4);
9498 
9499   strcpy(fname_stem, fname);
9500   dot = strrchr(fname_stem, '.');
9501   if(dot != NULL)
9502     if(strcmp(dot, ".img") == 0 || strcmp(dot, ".hdr") == 0)
9503       *dot = '\0';
9504 
9505   sprintf(hdr_fname, "%s.hdr", fname_stem);
9506   sprintf(img_fname, "%s.img", fname_stem);
9507 
9508   fp = fopen(hdr_fname, "w");
9509   if(fp == NULL)
9510     {
9511       errno = 0;
9512       ErrorReturn(ERROR_BADFILE,
9513                   (ERROR_BADFILE,
9514                    "nifti1Write(): error opening file %s", hdr_fname));
9515     }
9516 
9517   if(fwrite(&hdr, sizeof(hdr), 1, fp) != 1)
9518     {
9519       fclose(fp);
9520       errno = 0;
9521       ErrorReturn(ERROR_BADFILE,
9522                   (ERROR_BADFILE,
9523                    "nifti1Write(): error writing header to %s", hdr_fname));
9524     }
9525 
9526   fclose(fp);
9527 
9528   fp = fopen(img_fname, "w");
9529   if(fp == NULL)
9530     {
9531       errno = 0;
9532       ErrorReturn(ERROR_BADFILE,
9533                   (ERROR_BADFILE,
9534                    "nifti1Write(): error opening file %s", img_fname));
9535     }
9536 
9537   for(t = 0;t < mri->nframes;t++)
9538     for(k = 0;k < mri->depth;k++)
9539       for(j = 0;j < mri->height;j++)
9540         {
9541           buf = &MRIseq_vox(mri, 0, j, k, t);
9542           if(fwrite(buf, hdr.bitpix/8, mri->width, fp) != mri->width)
9543             {
9544               fclose(fp);
9545               errno = 0;
9546               ErrorReturn
9547                 (ERROR_BADFILE,
9548                  (ERROR_BADFILE,
9549                   "nifti1Write(): error writing data to %s", img_fname));
9550             }
9551         }
9552 
9553   fclose(fp);
9554 
9555   return(NO_ERROR);
9556 
9557 } /* end nifti1Write() */
9558 
9559 /*------------------------------------------------------------------
9560   niiRead() - note: there is also an nifti1Read(). Make sure to
9561   edit both.
9562   -----------------------------------------------------------------*/
9563 static MRI *niiRead(char *fname, int read_volume)
9564 {
9565 
9566   znzFile fp;
9567   MRI *mri;
9568   struct nifti_1_header hdr;
9569   int nslices;
9570   int fs_type;
9571   float time_units_factor, space_units_factor;
9572   int swapped_flag;
9573   int n_read, i, j, k, t;
9574   int bytes_per_voxel,time_units,space_units ;
9575 
9576   fp = znzopen(fname, "r", 1);
9577   if(fp == NULL){
9578     errno = 0;
9579     ErrorReturn(NULL, (ERROR_BADFILE,
9580                        "niiRead(): error opening file %s", fname));
9581   }
9582 
9583   if(znzread(&hdr, sizeof(hdr), 1, fp) != 1){
9584     znzclose(fp);
9585     errno = 0;
9586     ErrorReturn(NULL, (ERROR_BADFILE,
9587                        "niiRead(): error reading header from %s", fname));
9588   }
9589 
9590   znzclose(fp);
9591 
9592   swapped_flag = FALSE;
9593   if(hdr.dim[0] < 1 || hdr.dim[0] > 7){
9594     swapped_flag = TRUE;
9595     swap_nifti_1_header(&hdr);
9596     if(hdr.dim[0] < 1 || hdr.dim[0] > 7){
9597       ErrorReturn(NULL, (ERROR_BADFILE,
9598                          "niiRead(): bad number of dimensions (%hd) in %s",
9599                          hdr.dim[0], fname));
9600     }
9601   }
9602 
9603   if(memcmp(hdr.magic, NII_MAGIC, 4) != 0){
9604     ErrorReturn(NULL, (ERROR_BADFILE, "niiRead(): bad magic number in %s",
9605                        fname));
9606   }
9607 
9608   if(hdr.dim[0] != 3 && hdr.dim[0] != 4){
9609     ErrorReturn(NULL,
9610                 (ERROR_UNSUPPORTED,
9611                  "niiRead(): %hd dimensions in %s; unsupported",
9612                  hdr.dim[0], fname));
9613   }
9614 
9615   if(hdr.datatype == DT_NONE || hdr.datatype == DT_UNKNOWN){
9616     ErrorReturn(NULL,
9617                 (ERROR_UNSUPPORTED,
9618                  "niiRead(): unknown or no data type in %s; bailing out",
9619                  fname));
9620   }
9621 
9622   space_units  = XYZT_TO_SPACE(hdr.xyzt_units) ;
9623   if(space_units == NIFTI_UNITS_METER)       space_units_factor = 1000.0;
9624   else if(space_units == NIFTI_UNITS_MM)     space_units_factor = 1.0;
9625   else if(space_units == NIFTI_UNITS_MICRON) space_units_factor = 0.001;
9626   else
9627     ErrorReturn
9628       (NULL,
9629        (ERROR_BADFILE,
9630         "niiRead(): unknown space units %d in %s", space_units,
9631         fname));
9632 
9633   time_units = XYZT_TO_TIME (hdr.xyzt_units) ;
9634   if(time_units == NIFTI_UNITS_SEC)       time_units_factor = 1000.0;
9635   else if(time_units == NIFTI_UNITS_MSEC) time_units_factor = 1.0;
9636   else if(time_units == NIFTI_UNITS_USEC) time_units_factor = 0.001;
9637   else{
9638     if(hdr.dim[4] > 1){
9639       ErrorReturn
9640         (NULL,
9641          (ERROR_BADFILE,
9642           "niiRead(): unknown time units %d in %s",
9643           time_units,fname));
9644     }
9645     else time_units_factor = 0;
9646   }
9647   //printf("hdr.xyzt_units = %d, time_units = %d, %g, %g\n",
9648   // hdr.xyzt_units,time_units,hdr.pixdim[4],time_units_factor);
9649 
9650   /*
9651     nifti1.h says: slice_code = If this is nonzero, AND
9652     if slice_dim is nonzero, AND
9653     if slice_duration is positive, indicates the timing
9654     pattern of the slice acquisition.
9655     not yet supported here
9656   */
9657 
9658   if(hdr.slice_code != 0 && DIM_INFO_TO_SLICE_DIM(hdr.dim_info) != 0
9659      && hdr.slice_duration > 0.0){
9660     ErrorReturn(NULL,
9661                 (ERROR_UNSUPPORTED,
9662                  "niiRead(): unsupported timing pattern in %s", fname));
9663   }
9664 
9665   if(hdr.dim[0] == 3) nslices = 1;
9666   else                nslices = hdr.dim[4];
9667 
9668   if(hdr.scl_slope == 0){
9669     // voxel values are unscaled -- we use the file's data type
9670     if(hdr.datatype == DT_UNSIGNED_CHAR){
9671       fs_type = MRI_UCHAR;
9672       bytes_per_voxel = 1;
9673     }
9674     else if(hdr.datatype == DT_SIGNED_SHORT){
9675       fs_type = MRI_SHORT;
9676       bytes_per_voxel = 2;
9677     }
9678     else if(hdr.datatype == DT_SIGNED_INT){
9679       fs_type = MRI_INT;
9680       bytes_per_voxel = 4;
9681     }
9682     else if(hdr.datatype == DT_FLOAT){
9683       fs_type = MRI_FLOAT;
9684       bytes_per_voxel = 4;
9685     }
9686     else{
9687       ErrorReturn
9688         (NULL,
9689          (ERROR_UNSUPPORTED,
9690           "niiRead(): unsupported datatype %d (with scl_slope = 0) in %s",
9691           hdr.datatype, fname));
9692     }
9693   }
9694   else{
9695     // we must scale the voxel values
9696     if(   hdr.datatype != DT_UNSIGNED_CHAR
9697           && hdr.datatype != DT_SIGNED_SHORT
9698           && hdr.datatype != DT_SIGNED_INT
9699           && hdr.datatype != DT_FLOAT
9700           && hdr.datatype != DT_DOUBLE
9701           && hdr.datatype != DT_INT8
9702           && hdr.datatype != DT_UINT16
9703           && hdr.datatype != DT_UINT32){
9704       ErrorReturn
9705         (NULL,
9706          (ERROR_UNSUPPORTED,
9707           "niiRead(): unsupported datatype %d (with scl_slope != 0) in %s",
9708           hdr.datatype, fname));
9709     }
9710     fs_type = MRI_FLOAT;
9711     bytes_per_voxel = 0; /* set below -- avoid the compiler warning */
9712   }
9713 
9714   if(read_volume)
9715     mri = MRIallocSequence(hdr.dim[1],hdr.dim[2],hdr.dim[3],fs_type,nslices);
9716   else{
9717     mri = MRIallocHeader(hdr.dim[1], hdr.dim[2], hdr.dim[3], fs_type);
9718     mri->nframes = nslices;
9719   }
9720 
9721   if(mri == NULL) return(NULL);
9722 
9723   mri->xsize = hdr.pixdim[1];
9724   mri->ysize = hdr.pixdim[2];
9725   mri->zsize = hdr.pixdim[3];
9726   if(hdr.dim[0] == 4) mri->tr = hdr.pixdim[4];
9727 
9728   if(hdr.qform_code == 0){
9729     printf("WARNING: missing NIfTI-1 orientation (qform_code = 0)\n");
9730     printf("WARNING: your volume will probably be incorrectly oriented\n");
9731     mri->x_r = 1.0;  mri->x_a = 0.0;  mri->x_s = 0.0;
9732     mri->y_r = 0.0;  mri->y_a = 1.0;  mri->y_s = 0.0;
9733     mri->z_r = 0.0;  mri->z_a = 0.0;  mri->z_s = 1.0;
9734     mri->c_r = mri->xsize * mri->width / 2.0;
9735     mri->c_a = mri->ysize * mri->height / 2.0;
9736     mri->c_s = mri->zsize * mri->depth / 2.0;
9737   }
9738   else if(hdr.sform_code <= 0){
9739     if(niftiQformToMri(mri, &hdr) != NO_ERROR){
9740       MRIfree(&mri);
9741       return(NULL);
9742     }
9743   }
9744   else{
9745     if(niftiSformToMri(mri, &hdr) != NO_ERROR){
9746       MRIfree(&mri);
9747       return(NULL);
9748     }
9749   }
9750 
9751   mri->xsize = mri->xsize * space_units_factor;
9752   mri->ysize = mri->ysize * space_units_factor;
9753   mri->zsize = mri->zsize * space_units_factor;
9754   mri->c_r = mri->c_r * space_units_factor;
9755   mri->c_a = mri->c_a * space_units_factor;
9756   mri->c_s = mri->c_s * space_units_factor;
9757   if(hdr.dim[0] == 4)  mri->tr = mri->tr * time_units_factor;
9758 
9759   if(!read_volume) return(mri);
9760 
9761   fp = znzopen(fname, "r", 1);
9762   if(fp == NULL) {
9763     MRIfree(&mri);
9764     errno = 0;
9765     ErrorReturn(NULL, (ERROR_BADFILE,
9766                        "niiRead(): error opening file %s", fname));
9767   }
9768 
9769   if(znzseek(fp, (long)(hdr.vox_offset), SEEK_SET) == -1){
9770     znzclose(fp);
9771     MRIfree(&mri);
9772     errno = 0;
9773     ErrorReturn(NULL, (ERROR_BADFILE,
9774                        "niiRead(): error finding voxel data in %s", fname));
9775   }
9776 
9777   if(hdr.scl_slope == 0){
9778     // no voxel value scaling needed
9779     void *buf;
9780 
9781     for(t = 0;t < mri->nframes;t++)
9782       for(k = 0;k < mri->depth;k++)
9783         for(j = 0;j < mri->height;j++) {
9784           buf = &MRIseq_vox(mri, 0, j, k, t);
9785 
9786           n_read = znzread(buf, bytes_per_voxel, mri->width, fp);
9787           if(n_read != mri->width) {
9788             znzclose(fp);
9789             MRIfree(&mri);
9790             errno = 0;
9791             ErrorReturn(NULL, (ERROR_BADFILE,
9792                                "niiRead(): error reading from %s", fname));
9793           }
9794 
9795           if(swapped_flag) {
9796             if(bytes_per_voxel == 2)
9797               byteswapbufshort(buf, bytes_per_voxel * mri->width);
9798             if(bytes_per_voxel == 4)
9799               byteswapbuffloat(buf, bytes_per_voxel * mri->width);
9800           }
9801 
9802         }
9803 
9804   }
9805   else{
9806     // voxel value scaling needed
9807     if(hdr.datatype == DT_UNSIGNED_CHAR) {
9808       unsigned char *buf;
9809       bytes_per_voxel = 1;
9810       buf = (unsigned char *)malloc(mri->width * bytes_per_voxel);
9811       for(t = 0;t < mri->nframes;t++)
9812         for(k = 0;k < mri->depth;k++)
9813           for(j = 0;j < mri->height;j++) {
9814             n_read = znzread(buf, bytes_per_voxel, mri->width, fp);
9815             if(n_read != mri->width) {
9816               free(buf);
9817               znzclose(fp);
9818               MRIfree(&mri);
9819               errno = 0;
9820               ErrorReturn(NULL,
9821                           (ERROR_BADFILE,
9822                            "niiRead(): error reading from %s", fname));
9823             }
9824             for(i = 0;i < mri->width;i++)
9825               MRIFseq_vox(mri, i, j, k, t) =
9826                 hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
9827           }
9828       free(buf);
9829     }
9830 
9831     if(hdr.datatype == DT_SIGNED_SHORT){
9832       short *buf;
9833       bytes_per_voxel = 2;
9834       buf = (short *)malloc(mri->width * bytes_per_voxel);
9835       for(t = 0;t < mri->nframes;t++)
9836         for(k = 0;k < mri->depth;k++)
9837           for(j = 0;j < mri->height;j++) {
9838             n_read = znzread(buf, bytes_per_voxel, mri->width, fp);
9839             if(n_read != mri->width) {
9840               free(buf);
9841               znzclose(fp);
9842               MRIfree(&mri);
9843               errno = 0;
9844               ErrorReturn(NULL,
9845                           (ERROR_BADFILE,
9846                            "niiRead(): error reading from %s", fname));
9847             }
9848             if(swapped_flag)
9849               byteswapbufshort(buf, bytes_per_voxel * mri->width);
9850             for(i = 0;i < mri->width;i++)
9851               MRIFseq_vox(mri, i, j, k, t) =
9852                 hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
9853           }
9854       free(buf);
9855     }
9856 
9857     if(hdr.datatype == DT_SIGNED_INT) {
9858       int *buf;
9859       bytes_per_voxel = 4;
9860       buf = (int *)malloc(mri->width * bytes_per_voxel);
9861       for(t = 0;t < mri->nframes;t++)
9862         for(k = 0;k < mri->depth;k++)
9863           for(j = 0;j < mri->height;j++) {
9864             n_read = znzread(buf, bytes_per_voxel, mri->width, fp);
9865             if(n_read != mri->width){
9866               free(buf);
9867               znzclose(fp);
9868               MRIfree(&mri);
9869               errno = 0;
9870               ErrorReturn(NULL,
9871                           (ERROR_BADFILE,
9872                            "niiRead(): error reading from %s", fname));
9873             }
9874             if(swapped_flag)
9875               byteswapbuffloat(buf, bytes_per_voxel * mri->width);
9876             for(i = 0;i < mri->width;i++)
9877               MRIFseq_vox(mri, i, j, k, t) =
9878                 hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
9879           }
9880       free(buf);
9881     }
9882 
9883     if(hdr.datatype == DT_FLOAT) {
9884       float *buf;
9885       bytes_per_voxel = 4;
9886       buf = (float *)malloc(mri->width * bytes_per_voxel);
9887       for(t = 0;t < mri->nframes;t++)
9888         for(k = 0;k < mri->depth;k++)
9889           for(j = 0;j < mri->height;j++) {
9890             n_read = znzread(buf, bytes_per_voxel, mri->width, fp);
9891             if(n_read != mri->width) {
9892               free(buf);
9893               znzclose(fp);
9894               MRIfree(&mri);
9895               errno = 0;
9896               ErrorReturn(NULL,
9897                           (ERROR_BADFILE,
9898                            "niiRead(): error reading from %s", fname));
9899             }
9900             if(swapped_flag)
9901               byteswapbuffloat(buf, bytes_per_voxel * mri->width);
9902             for(i = 0;i < mri->width;i++)
9903               MRIFseq_vox(mri, i, j, k, t) =
9904                 hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
9905           }
9906       free(buf);
9907     }
9908 
9909     if(hdr.datatype == DT_DOUBLE) {
9910       double *buf;
9911       unsigned char *cbuf, ccbuf[8];
9912       bytes_per_voxel = 8;
9913       buf = (double *)malloc(mri->width * bytes_per_voxel);
9914       for(t = 0;t < mri->nframes;t++)
9915         for(k = 0;k < mri->depth;k++)
9916           for(j = 0;j < mri->height;j++) {
9917             n_read = znzread(buf, bytes_per_voxel, mri->width, fp);
9918             if(n_read != mri->width) {
9919               free(buf);
9920               znzclose(fp);
9921               MRIfree(&mri);
9922               errno = 0;
9923               ErrorReturn(NULL,
9924                           (ERROR_BADFILE,
9925                            "niiRead(): error reading from %s", fname));
9926             }
9927             if(swapped_flag) {
9928               for(i = 0;i < mri->width;i++)
9929                 {
9930                   cbuf = (unsigned char *)&buf[i];
9931                   memcpy(ccbuf, cbuf, 8);
9932                   cbuf[0] = ccbuf[7];
9933                   cbuf[1] = ccbuf[6];
9934                   cbuf[2] = ccbuf[5];
9935                   cbuf[3] = ccbuf[4];
9936                   cbuf[4] = ccbuf[3];
9937                   cbuf[5] = ccbuf[2];
9938                   cbuf[6] = ccbuf[1];
9939                   cbuf[7] = ccbuf[0];
9940                 }
9941             }
9942             for(i = 0;i < mri->width;i++)
9943               MRIFseq_vox(mri, i, j, k, t) =
9944                 hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
9945           }
9946       free(buf);
9947     }
9948 
9949     if(hdr.datatype == DT_INT8) {
9950       char *buf;
9951       bytes_per_voxel = 1;
9952       buf = (char *)malloc(mri->width * bytes_per_voxel);
9953       for(t = 0;t < mri->nframes;t++)
9954         for(k = 0;k < mri->depth;k++)
9955           for(j = 0;j < mri->height;j++){
9956             n_read = znzread(buf, bytes_per_voxel, mri->width, fp);
9957             if(n_read != mri->width) {
9958               free(buf);
9959               znzclose(fp);
9960               MRIfree(&mri);
9961               errno = 0;
9962               ErrorReturn(NULL,
9963                           (ERROR_BADFILE,
9964                            "niiRead(): error reading from %s", fname));
9965             }
9966             for(i = 0;i < mri->width;i++)
9967               MRIFseq_vox(mri, i, j, k, t) =
9968                 hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
9969           }
9970       free(buf);
9971     }
9972 
9973     if(hdr.datatype == DT_UINT16) {
9974       unsigned short *buf;
9975       bytes_per_voxel = 2;
9976       buf = (unsigned short *)malloc(mri->width * bytes_per_voxel);
9977       for(t = 0;t < mri->nframes;t++)
9978         for(k = 0;k < mri->depth;k++)
9979           for(j = 0;j < mri->height;j++) {
9980             n_read = znzread(buf, bytes_per_voxel, mri->width, fp);
9981             if(n_read != mri->width){
9982               free(buf);
9983               znzclose(fp);
9984               MRIfree(&mri);
9985               errno = 0;
9986               ErrorReturn(NULL,
9987                           (ERROR_BADFILE,
9988                            "niiRead(): error reading from %s", fname));
9989             }
9990             if(swapped_flag)
9991               byteswapbufshort(buf, bytes_per_voxel * mri->width);
9992             for(i = 0;i < mri->width;i++)
9993               MRIFseq_vox(mri, i, j, k, t) =
9994                 hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
9995           }
9996       free(buf);
9997     }
9998 
9999     if(hdr.datatype == DT_UINT32) {
10000       unsigned int *buf;
10001       bytes_per_voxel = 4;
10002       buf = (unsigned int *)malloc(mri->width * bytes_per_voxel);
10003       for(t = 0;t < mri->nframes;t++)
10004         for(k = 0;k < mri->depth;k++)
10005           for(j = 0;j < mri->height;j++)
10006             {
10007               n_read = znzread(buf, bytes_per_voxel, mri->width, fp);
10008               if(n_read != mri->width)
10009                 {
10010                   free(buf);
10011                   znzclose(fp);
10012                   MRIfree(&mri);
10013                   errno = 0;
10014                   ErrorReturn(NULL,
10015                               (ERROR_BADFILE,
10016                                "niiRead(): error reading from %s", fname));
10017                 }
10018               if(swapped_flag)
10019                 byteswapbuffloat(buf, bytes_per_voxel * mri->width);
10020               for(i = 0;i < mri->width;i++)
10021                 MRIFseq_vox(mri, i, j, k, t) =
10022                   hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
10023             }
10024       free(buf);
10025     }
10026   }
10027   znzclose(fp);
10028 
10029   return(mri);
10030 
10031 } /* end niiRead() */
10032 
10033 /*------------------------------------------------------------------
10034   niiWrite() - note: there is also an nifti1Write(). Make sure to
10035   edit both.
10036   -----------------------------------------------------------------*/
10037 static int niiWrite(MRI *mri, char *fname)
10038 {
10039 
10040   znzFile fp;
10041   int j, k, t;
10042   BUFTYPE *buf;
10043   struct nifti_1_header hdr;
10044   int error;
10045 
10046   memset(&hdr, 0x00, sizeof(hdr));
10047 
10048   hdr.sizeof_hdr = 348;
10049   hdr.dim_info = 0;
10050 
10051   if(mri->nframes == 1){
10052     hdr.dim[0] = 3;
10053     hdr.dim[1] = mri->width;
10054     hdr.dim[2] = mri->height;
10055     hdr.dim[3] = mri->depth;
10056     hdr.pixdim[1] = mri->xsize;
10057     hdr.pixdim[2] = mri->ysize;
10058     hdr.pixdim[3] = mri->zsize;
10059   }
10060   else{
10061     hdr.dim[0] = 4;
10062     hdr.dim[1] = mri->width;
10063     hdr.dim[2] = mri->height;
10064     hdr.dim[3] = mri->depth;
10065     hdr.dim[4] = mri->nframes;
10066     hdr.pixdim[1] = mri->xsize;
10067     hdr.pixdim[2] = mri->ysize;
10068     hdr.pixdim[3] = mri->zsize;
10069     hdr.pixdim[4] = mri->tr/1000.0; // see also xyzt_units
10070   }
10071 
10072   if(mri->type == MRI_UCHAR){
10073     hdr.datatype = DT_UNSIGNED_CHAR;
10074     hdr.bitpix = 8;
10075   }
10076   else if(mri->type == MRI_INT){
10077     hdr.datatype = DT_SIGNED_INT;
10078     hdr.bitpix = 32;
10079   }
10080   else if(mri->type == MRI_LONG){
10081     hdr.datatype = DT_SIGNED_INT;
10082     hdr.bitpix = 32;
10083   }
10084   else if(mri->type == MRI_FLOAT){
10085     hdr.datatype = DT_FLOAT;
10086     hdr.bitpix = 32;
10087   }
10088   else if(mri->type == MRI_SHORT){
10089     hdr.datatype = DT_SIGNED_SHORT;
10090     hdr.bitpix = 16;
10091   }
10092   else if(mri->type == MRI_BITMAP){
10093     ErrorReturn(ERROR_UNSUPPORTED,
10094                 (ERROR_UNSUPPORTED,
10095                  "niiWrite(): data type MRI_BITMAP unsupported"));
10096   }
10097   else if(mri->type == MRI_TENSOR){
10098     ErrorReturn(ERROR_UNSUPPORTED,
10099                 (ERROR_UNSUPPORTED,
10100                  "niiWrite(): data type MRI_TENSOR unsupported"));
10101   }
10102   else{
10103     ErrorReturn(ERROR_BADPARM,
10104                 (ERROR_BADPARM,
10105                  "niiWrite(): unknown data type %d", mri->type));
10106   }
10107 
10108   hdr.intent_code = NIFTI_INTENT_NONE;
10109   hdr.intent_name[0] = '\0';
10110   hdr.vox_offset = sizeof(hdr);
10111   hdr.scl_slope = 0.0;
10112   hdr.slice_code = 0;
10113   hdr.xyzt_units = NIFTI_UNITS_MM | NIFTI_UNITS_SEC;
10114   hdr.cal_max = 0.0;
10115   hdr.cal_min = 0.0;
10116   hdr.toffset = 0;
10117 
10118   /* set the nifti header qform values */
10119   error = mriToNiftiQform(mri, &hdr);
10120   if(error != NO_ERROR)
10121     return(error);
10122 
10123   memcpy(hdr.magic, NII_MAGIC, 4);
10124 
10125   fp = znzopen(fname, "w", 1);
10126   if(fp == NULL){
10127     errno = 0;
10128     ErrorReturn(ERROR_BADFILE,
10129                 (ERROR_BADFILE,
10130                  "niiWrite(): error opening file %s", fname));
10131   }
10132 
10133   if(znzwrite(&hdr, sizeof(hdr), 1, fp) != 1) {
10134     znzclose(fp);
10135     errno = 0;
10136     ErrorReturn(ERROR_BADFILE,
10137                 (ERROR_BADFILE,
10138                  "niiWrite(): error writing header to %s", fname));
10139   }
10140 
10141   for(t = 0;t < mri->nframes;t++)
10142     for(k = 0;k < mri->depth;k++)
10143       for(j = 0;j < mri->height;j++){
10144         buf = &MRIseq_vox(mri, 0, j, k, t);
10145         if(znzwrite(buf, hdr.bitpix/8, mri->width, fp) != mri->width){
10146           znzclose(fp);
10147           errno = 0;
10148           ErrorReturn(ERROR_BADFILE,
10149                       (ERROR_BADFILE,
10150                        "niiWrite(): error writing data to %s", fname));
10151         }
10152       }
10153 
10154   znzclose(fp);
10155 
10156   return(NO_ERROR);
10157 
10158 } /* end niiWrite() */
10159 
10160 static int niftiSformToMri(MRI *mri, struct nifti_1_header *hdr)
10161 {
10162 
10163   /*
10164 
10165   x = srow_x[0] * i + srow_x[1] * j + srow_x[2] * k + srow_x[3]
10166   y = srow_y[0] * i + srow_y[1] * j + srow_y[2] * k + srow_y[3]
10167   z = srow_z[0] * i + srow_z[1] * j + srow_z[2] * k + srow_z[3]
10168 
10169 
10170   [ r ]   [ mri->xsize * mri->x_r
10171   mri->ysize * mri->y_r    mri->zsize * mri->z_r  r_offset ]   [ i ]
10172   [ a ] = [ mri->xsize * mri->x_a
10173   mri->ysize * mri->y_a    mri->zsize * mri->z_a  a_offset ] * [ j ]
10174   [ s ]   [ mri->xsize * mri->x_s
10175   mri->ysize * mri->y_s    mri->zsize * mri->z_s  s_offset ]   [ k ]
10176   [ 1 ]   [            0
10177   0                        0              1     ]   [ 1 ]
10178 
10179 
10180 
10181   */
10182 
10183   mri->xsize = sqrt(hdr->srow_x[0]*hdr->srow_x[0] \
10184                     + hdr->srow_y[0]*hdr->srow_y[0] \
10185                     + hdr->srow_z[0]*hdr->srow_z[0]);
10186   mri->x_r = hdr->srow_x[0] / mri->xsize;
10187   mri->x_a = hdr->srow_y[0] / mri->ysize;
10188   mri->x_s = hdr->srow_z[0] / mri->zsize;
10189 
10190   mri->ysize = sqrt(hdr->srow_x[1]*hdr->srow_x[1] \
10191                     + hdr->srow_y[1]*hdr->srow_y[1] \
10192                     + hdr->srow_z[1]*hdr->srow_z[1]);
10193   mri->y_r = hdr->srow_x[1] / mri->ysize;
10194   mri->y_a = hdr->srow_y[1] / mri->ysize;
10195   mri->y_s = hdr->srow_z[1] / mri->ysize;
10196 
10197   mri->zsize = sqrt(hdr->srow_x[2]*hdr->srow_x[2] \
10198                     + hdr->srow_y[2]*hdr->srow_y[2] \
10199                     + hdr->srow_z[2]*hdr->srow_z[2]);
10200   mri->z_r = hdr->srow_x[2] / mri->zsize;
10201   mri->z_a = hdr->srow_y[2] / mri->zsize;
10202   mri->z_s = hdr->srow_z[2] / mri->zsize;
10203 
10204   mri->c_r =   hdr->srow_x[0] * mri->width / 2.0
10205     + hdr->srow_x[1] * mri->height / 2.0
10206     + hdr->srow_x[2] * mri->depth / 2.0
10207     + hdr->srow_x[3];
10208 
10209   mri->c_a =   hdr->srow_y[0] * mri->width / 2.0
10210     + hdr->srow_y[1] * mri->height / 2.0
10211     + hdr->srow_y[2] * mri->depth / 2.0
10212     + hdr->srow_y[3];
10213 
10214   mri->c_r =   hdr->srow_z[0] * mri->width / 2.0
10215     + hdr->srow_z[1] * mri->height / 2.0
10216     + hdr->srow_z[2] * mri->depth / 2.0
10217     + hdr->srow_z[3];
10218 
10219   return(NO_ERROR);
10220 
10221 } /* end niftiSformToMri() */
10222 
10223 static int niftiQformToMri(MRI *mri, struct nifti_1_header *hdr)
10224 {
10225 
10226   float a, b, c, d;
10227   float r11, r12, r13;
10228   float r21, r22, r23;
10229   float r31, r32, r33;
10230 
10231   b = hdr->quatern_b;
10232   c = hdr->quatern_c;
10233   d = hdr->quatern_d;
10234 
10235   /* following quatern_to_mat44() */
10236 
10237   a = 1.0 - (b*b + c*c + d*d);
10238   if(a < 1.0e-7)
10239     {
10240       a = 1.0 / sqrt(b*b + c*c + d*d);
10241       b *= a;
10242       c *= a;
10243       d *= a;
10244       a = 0.0;
10245     }
10246   else
10247     a = sqrt(a);
10248 
10249   r11 = a*a + b*b - c*c - d*d;
10250   r12 = 2.0*b*c - 2.0*a*d;
10251   r13 = 2.0*b*d + 2.0*a*c;
10252   r21 = 2.0*b*c + 2.0*a*d;
10253   r22 = a*a + c*c - b*b - d*d;
10254   r23 = 2.0*c*d - 2.0*a*b;
10255   r31 = 2.0*b*d - 2*a*c;
10256   r32 = 2.0*c*d + 2*a*b;
10257   r33 = a*a + d*d - c*c - b*b;
10258 
10259   if(hdr->pixdim[0] < 0.0)
10260     {
10261       r13 = -r13;
10262       r23 = -r23;
10263       r33 = -r33;
10264     }
10265 
10266   mri->x_r = r11;
10267   mri->y_r = r12;
10268   mri->z_r = r13;
10269   mri->x_a = r21;
10270   mri->y_a = r22;
10271   mri->z_a = r23;
10272   mri->x_s = r31;
10273   mri->y_s = r32;
10274   mri->z_s = r33;
10275 
10276 
10277   /**/
10278   /* c_ras */
10279   /*
10280 
10281   [ r ]   [ mri->xsize * mri->x_r
10282   mri->ysize * mri->y_r    mri->zsize * mri->z_r  r_offset ]   [ i ]
10283   [ a ] = [ mri->xsize * mri->x_a
10284   mri->ysize * mri->y_a    mri->zsize * mri->z_a  a_offset ] * [ j ]
10285   [ s ]   [ mri->xsize * mri->x_s
10286   mri->ysize * mri->y_s    mri->zsize * mri->z_s  s_offset ]   [ k ]
10287   [ 1 ]   [            0
10288   0                        0              1     ]   [ 1 ]
10289 
10290 
10291   */
10292 
10293   mri->c_r =   (mri->xsize * mri->x_r) * (mri->width / 2.0)
10294     + (mri->ysize * mri->y_r) * (mri->height / 2.0)
10295     + (mri->zsize * mri->z_r) * (mri->depth / 2.0)
10296     + hdr->qoffset_x;
10297 
10298   mri->c_a =   (mri->xsize * mri->x_a) * (mri->width / 2.0)
10299     + (mri->ysize * mri->y_a) * (mri->height / 2.0)
10300     + (mri->zsize * mri->z_a) * (mri->depth / 2.0)
10301     + hdr->qoffset_y;
10302 
10303   mri->c_s =   (mri->xsize * mri->x_s) * (mri->width / 2.0)
10304     + (mri->ysize * mri->y_s) * (mri->height / 2.0)
10305     + (mri->zsize * mri->z_s) * (mri->depth / 2.0)
10306     + hdr->qoffset_z;
10307 
10308 
10309   return(NO_ERROR);
10310 
10311 } /* end niftiQformToMri() */
10312 
10313 static int mriToNiftiQform(MRI *mri, struct nifti_1_header *hdr)
10314 {
10315 
10316   MATRIX *i_to_r;
10317   float r11, r12, r13;
10318   float r21, r22, r23;
10319   float r31, r32, r33;
10320   float qfac;
10321   float a, b, c, d;
10322   float xd, yd, zd;
10323   float r_det;
10324 
10325   /*
10326 
10327   nifti1.h (x, y, z are r, a, s, respectively):
10328 
10329   [ x ]   [ R11 R12 R13 ] [        pixdim[1] * i ]   [ qoffset_x ]
10330   [ y ] = [ R21 R22 R23 ] [        pixdim[2] * j ] + [ qoffset_y ]
10331   [ z ]   [ R31 R32 R33 ] [ qfac * pixdim[3] * k ]   [ qoffset_z ]
10332 
10333   mri.c extract_r_to_i():
10334 
10335   [ r ]   [ mri->xsize * mri->x_r
10336   mri->ysize * mri->y_r    mri->zsize * mri->z_r  r_offset ]   [ i ]
10337   [ a ] = [ mri->xsize * mri->x_a
10338   mri->ysize * mri->y_a    mri->zsize * mri->z_a  a_offset ] * [ j ]
10339   [ s ]   [ mri->xsize * mri->x_s
10340   mri->ysize * mri->y_s    mri->zsize * mri->z_s  s_offset ]   [ k ]
10341   [ 1 ]   [            0
10342   0                        0              1     ]   [ 1 ]
10343 
10344   where [ras]_offset are calculated by satisfying (r, a, s)
10345   = (mri->c_r, mri->c_a, mri->c_s)
10346   when (i, j, k) = (mri->width/2, mri->height/2, mri->depth/2)
10347 
10348   so our mapping is simple:
10349 
10350   (done outside this function)
10351   pixdim[1] mri->xsize
10352   pixdim[2] mri->ysize
10353   pixdim[3] mri->zsize
10354 
10355   R11 = mri->x_r  R12 = mri->y_r  R13 = mri->z_r
10356   R21 = mri->x_a  R22 = mri->y_a  R23 = mri->z_a
10357   R31 = mri->x_s  R32 = mri->y_s  R33 = mri->z_s
10358 
10359   qoffset_x = r_offset
10360   qoffset_y = a_offset
10361   qoffset_z = s_offset
10362 
10363   qfac (pixdim[0]) = 1
10364 
10365   unless det(R) == -1, in which case we substitute:
10366 
10367   R13 = -mri->z_r
10368   R23 = -mri->z_a
10369   R33 = -mri->z_s
10370 
10371   qfac (pixdim[0]) = -1
10372 
10373   we follow mat44_to_quatern() from nifti1_io.c
10374 
10375   for now, assume orthonormality in mri->[xyz]_[ras]
10376 
10377   */
10378 
10379 
10380   r11 = mri->x_r;  r12 = mri->y_r;  r13 = mri->z_r;
10381   r21 = mri->x_a;  r22 = mri->y_a;  r23 = mri->z_a;
10382   r31 = mri->x_s;  r32 = mri->y_s;  r33 = mri->z_s;
10383 
10384   r_det = + r11 * (r22*r33 - r32*r23)
10385     - r12 * (r21*r33 - r31*r23)
10386     + r13 * (r21*r32 - r31*r22);
10387 
10388   if(r_det == 0.0)
10389     {
10390       ErrorReturn(ERROR_BADFILE,
10391                   (ERROR_BADFILE,
10392                    "bad orientation matrix (determinant = 0) in nifti1 file"));
10393     }
10394   else if(r_det > 0.0)
10395     qfac = 1.0;
10396   else
10397     {
10398       r13 = -r13;
10399       r23 = -r23;
10400       r33 = -r33;
10401       qfac = -1.0;
10402     }
10403 
10404   /* following mat44_to_quatern() */
10405 
10406   a = r11 + r22 + r33 + 1.0;
10407 
10408   if(a > 0.5)
10409     {
10410       a = 0.5 * sqrt(a);
10411       b = 0.25 * (r32-r23) / a;
10412       c = 0.25 * (r13-r31) / a;
10413       d = 0.25 * (r21-r12) / a;
10414     }
10415   else
10416     {
10417 
10418       xd = 1.0 + r11 - (r22+r33);
10419       yd = 1.0 + r22 - (r11+r33);
10420       zd = 1.0 + r33 - (r11+r22);
10421 
10422       if(xd > 1.0)
10423         {
10424           b = 0.5 * sqrt(xd);
10425           c = 0.25 * (r12+r21) / b;
10426           d = 0.25 * (r13+r31) / b;
10427           a = 0.25 * (r32-r23) / b;
10428         }
10429       else if( yd > 1.0 )
10430         {
10431           c = 0.5 * sqrt(yd);
10432           b = 0.25 * (r12+r21) / c;
10433           d = 0.25 * (r23+r32) / c;
10434           a = 0.25 * (r13-r31) / c;
10435         }
10436       else
10437         {
10438           d = 0.5 * sqrt(zd);
10439           b = 0.25 * (r13+r31) / d;
10440           c = 0.25 * (r23+r32) / d;
10441           a = 0.25 * (r21-r12) / d;
10442         }
10443 
10444       if(a < 0.0)
10445         {
10446           a = -a;
10447           b = -b;
10448           c = -c;
10449           d = -d;
10450         }
10451 
10452     }
10453 
10454   hdr->qform_code = NIFTI_XFORM_SCANNER_ANAT;
10455 
10456   hdr->pixdim[0] = qfac;
10457 
10458   hdr->quatern_b = b;
10459   hdr->quatern_c = c;
10460   hdr->quatern_d = d;
10461 
10462   i_to_r = extract_i_to_r(mri);
10463   if(i_to_r == NULL)
10464     return(ERROR_BADPARM);
10465 
10466   hdr->qoffset_x = *MATRIX_RELT(i_to_r, 1, 4);
10467   hdr->qoffset_y = *MATRIX_RELT(i_to_r, 2, 4);
10468   hdr->qoffset_z = *MATRIX_RELT(i_to_r, 3, 4);
10469 
10470   MatrixFree(&i_to_r);
10471 
10472   return(NO_ERROR);
10473 
10474 } /* end mriToNiftiQform() */
10475 
10476 static void swap_nifti_1_header(struct nifti_1_header *hdr)
10477 {
10478 
10479   int i;
10480 
10481   hdr->sizeof_hdr = swapInt(hdr->sizeof_hdr);
10482 
10483   for(i = 0;i < 8;i++)
10484     hdr->dim[i] = swapShort(hdr->dim[i]);
10485 
10486   hdr->intent_p1 = swapFloat(hdr->intent_p1);
10487   hdr->intent_p2 = swapFloat(hdr->intent_p2);
10488   hdr->intent_p3 = swapFloat(hdr->intent_p3);
10489   hdr->intent_code = swapShort(hdr->intent_code);
10490   hdr->datatype = swapShort(hdr->datatype);
10491   hdr->bitpix = swapShort(hdr->bitpix);
10492   hdr->slice_start = swapShort(hdr->slice_start);
10493 
10494   for(i = 0;i < 8;i++)
10495     hdr->pixdim[i] = swapFloat(hdr->pixdim[i]);
10496 
10497   hdr->vox_offset = swapFloat(hdr->vox_offset);
10498   hdr->scl_slope = swapFloat(hdr->scl_slope);
10499   hdr->scl_inter = swapFloat(hdr->scl_inter);
10500   hdr->slice_end = swapShort(hdr->slice_end);
10501   hdr->cal_max = swapFloat(hdr->cal_max);
10502   hdr->cal_min = swapFloat(hdr->cal_min);
10503   hdr->slice_duration = swapFloat(hdr->slice_duration);
10504   hdr->toffset = swapFloat(hdr->toffset);
10505   hdr->qform_code = swapShort(hdr->qform_code);
10506   hdr->sform_code = swapShort(hdr->sform_code);
10507   hdr->quatern_b = swapFloat(hdr->quatern_b);
10508   hdr->quatern_c = swapFloat(hdr->quatern_c);
10509   hdr->quatern_d = swapFloat(hdr->quatern_d);
10510   hdr->qoffset_x = swapFloat(hdr->qoffset_x);
10511   hdr->qoffset_y = swapFloat(hdr->qoffset_y);
10512   hdr->qoffset_z = swapFloat(hdr->qoffset_z);
10513 
10514   for(i = 0;i < 4;i++)
10515     hdr->srow_x[i] = swapFloat(hdr->srow_x[i]);
10516 
10517   for(i = 0;i < 4;i++)
10518     hdr->srow_y[i] = swapFloat(hdr->srow_y[i]);
10519 
10520   for(i = 0;i < 4;i++)
10521     hdr->srow_z[i] = swapFloat(hdr->srow_z[i]);
10522 
10523   return;
10524 
10525 } /* end swap_nifti_1_header */
10526 
10527 MRI *MRIreadGeRoi(char *fname, int n_slices)
10528 {
10529 
10530   MRI *mri;
10531   int i;
10532   char prefix[STRLEN], postfix[STRLEN];
10533   int n_digits;
10534   FILE *fp;
10535   int width, height;
10536   char fname_use[STRLEN];
10537   int read_one_flag;
10538   int pixel_data_offset;
10539   int y;
10540 
10541   if((fp = fopen(fname, "r")) == NULL)
10542     {
10543       errno = 0;
10544       ErrorReturn
10545         (NULL,
10546          (ERROR_BADFILE, "MRIreadGeRoi(): error opening file %s", fname));
10547     }
10548 
10549   fseek(fp, 8, SEEK_SET);
10550   fread(&width, 4, 1, fp);  width = orderIntBytes(width);
10551   fread(&height, 4, 1, fp);  height = orderIntBytes(height);
10552 
10553   fclose(fp);
10554 
10555   for(i = strlen(fname);i >= 0 && fname[i] != '/';i--);
10556   i++;
10557 
10558   n_digits = 0;
10559   for(;fname[i] != '\0' && n_digits < 3;i++)
10560     {
10561       if(isdigit(fname[i]))
10562         n_digits++;
10563       else
10564         n_digits = 0;
10565     }
10566 
10567   if(n_digits < 3)
10568     {
10569       errno = 0;
10570       ErrorReturn(NULL, (ERROR_BADPARM,
10571                          "MRIreadGeRoi(): bad GE file name (couldn't find "
10572                          "three consecutive digits in the base file name)"));
10573     }
10574 
10575   strcpy(prefix, fname);
10576   prefix[i-3] = '\0';
10577 
10578   strcpy(postfix, &(fname[i]));
10579 
10580   printf("%s---%s\n", prefix, postfix);
10581 
10582   mri = MRIalloc(width, height, n_slices, MRI_SHORT);
10583 
10584   if(mri == NULL)
10585     {
10586       errno = 0;
10587       ErrorReturn
10588         (NULL,
10589          (ERROR_NOMEMORY, "MRIreadGeRoi(): couldn't allocate MRI structure"));
10590     }
10591 
10592   MRIclear(mri);
10593 
10594   read_one_flag = FALSE;
10595 
10596   for(i = 0;i < n_slices;i++)
10597     {
10598 
10599       sprintf(fname_use, "%s%03d%s", prefix, i, postfix);
10600       if((fp = fopen(fname_use, "r")) != NULL)
10601         {
10602 
10603           fseek(fp, 4, SEEK_SET);
10604           fread(&pixel_data_offset, 4, 1, fp);
10605           pixel_data_offset = orderIntBytes(pixel_data_offset);
10606           fseek(fp, pixel_data_offset, SEEK_SET);
10607 
10608           for(y = 0;y < mri->height;y++)
10609             {
10610               if(fread(mri->slices[i][y], 2, mri->width, fp) != mri->width)
10611                 {
10612                   fclose(fp);
10613                   MRIfree(&mri);
10614                   errno = 0;
10615                   ErrorReturn
10616                     (NULL,
10617                      (ERROR_BADFILE,
10618                       "MRIreadGeRoi(): error reading from file file %s",
10619                       fname_use));
10620                 }
10621 #if (BYTE_ORDER == LITTLE_ENDIAN)
10622               swab(mri->slices[i][y], mri->slices[i][y], 2 * mri->width);
10623 #endif
10624             }
10625 
10626           fclose(fp);
10627           read_one_flag = TRUE;
10628 
10629         }
10630     }
10631 
10632   if(!read_one_flag)
10633     {
10634       MRIfree(&mri);
10635       errno = 0;
10636       ErrorReturn
10637         (NULL, (ERROR_BADFILE, "MRIreadGeRoi(): didn't read any ROI files"));
10638     }
10639 
10640   return(mri);
10641 
10642 } /* end MRIreadGeRoi() */
10643 
10644 /*******************************************************************/
10645 /*******************************************************************/
10646 /*******************************************************************/
10647 
10648 static int data_size[] = { 1, 4, 4, 4, 2 };
10649 
10650 static MRI *sdtRead(char *fname, int read_volume)
10651 {
10652 
10653   char header_fname[STR_LEN];
10654   char line[STR_LEN];
10655   char *colon, *dot;
10656   FILE *fp;
10657   MRI *mri;
10658   int ndim = -1, data_type = -1;
10659   int dim[4];
10660   float xsize = 1.0, ysize = 1.0, zsize = 1.0, dummy_size;
10661   int orientation = MRI_CORONAL;
10662 
10663   dim[0] = -1;
10664   dim[1] = -1;
10665   dim[2] = -1;
10666   dim[3] = -1;
10667 
10668   /* form the header file name */
10669   strcpy(header_fname, fname);
10670   if((dot = strrchr(header_fname, '.')))
10671     sprintf(dot+1, "spr");
10672   else
10673     strcat(header_fname, ".spr");
10674 
10675   /* open the header */
10676   if((fp = fopen(header_fname, "r")) == NULL)
10677     {
10678       errno = 0;
10679       ErrorReturn
10680         (NULL,
10681          (ERROR_BADFILE,
10682           "sdtRead(%s): could not open header file %s\n",
10683           fname, header_fname));
10684     }
10685 
10686   while(1) // !feof(fp))
10687     {
10688       fgets(line, STR_LEN, fp);
10689       if (feof(fp)) // wow.  we read too many.  get out
10690         break;
10691 
10692       if((colon = strchr(line, ':')))
10693         {
10694           *colon = '\0';
10695           colon++;
10696           if(strcmp(line, "numDim") == 0)
10697             {
10698               sscanf(colon, "%d", &ndim);
10699               if(ndim < 3 || ndim > 4)
10700                 {
10701                   fclose(fp);
10702                   errno = 0;
10703                   ErrorReturn
10704                     (NULL,
10705                      (ERROR_UNSUPPORTED,
10706                       "sdtRead(%s): only 3 or 4 dimensions "
10707                       "supported (numDim = %d)\n",
10708                       fname, ndim));
10709                 }
10710             }
10711           else if(strcmp(line, "dim") == 0)
10712             {
10713               if(ndim == -1)
10714                 {
10715                   fclose(fp);
10716                   errno = 0;
10717                   ErrorReturn
10718                     (NULL,
10719                      (ERROR_BADFILE,
10720                       "sdtRead(%s): 'dim' before 'numDim' in header file %s\n",
10721                       fname, header_fname));
10722                 }
10723               if(ndim == 3)
10724                 {
10725                   sscanf(colon, "%d %d %d", &dim[0], &dim[1], &dim[2]);
10726                   dim[3] = 1;
10727                 }
10728               else
10729                 {
10730                   sscanf(colon, "%d %d %d %d",
10731                          &dim[0], &dim[1], &dim[2], &dim[3]);
10732                   if(dim[3] != 1)
10733                     {
10734                       fclose(fp);
10735                       errno = 0;
10736                       ErrorReturn
10737                         (NULL,
10738                          (ERROR_UNSUPPORTED,
10739                           "sdtRead(%s): nframes != 1 unsupported "
10740                           "for sdt (dim(4) = %d)\n",
10741                           fname, dim[3]));
10742                     }
10743                 }
10744             }
10745           else if(strcmp(line, "dataType") == 0)
10746             {
10747               while(isspace((int)*colon))
10748                 colon++;
10749               if(strncmp(colon, "BYTE", 4) == 0)
10750                 data_type = MRI_UCHAR;
10751               else if(strncmp(colon, "WORD", 4) == 0)
10752                 data_type = MRI_SHORT;
10753               else if(strncmp(colon, "LWORD", 5) == 0)
10754                 data_type = MRI_INT;
10755               else if(strncmp(colon, "REAL", 4) == 0)
10756                 data_type = MRI_FLOAT;
10757               else if(strncmp(colon, "COMPLEX", 7) == 0)
10758                 {
10759                   fclose(fp);
10760                   errno = 0;
10761                   ErrorReturn
10762                     (NULL,
10763                      (ERROR_UNSUPPORTED,
10764                       "sdtRead(%s): unsupported data type '%s'\n",
10765                       fname, colon));
10766                 }
10767               else
10768                 {
10769                   fclose(fp);
10770                   errno = 0;
10771                   ErrorReturn
10772                     (NULL,
10773                      (ERROR_BADFILE,
10774                       "sdtRead(%s): unknown data type '%s'\n", fname, colon));
10775                 }
10776             }
10777           else if(strcmp(line, "interval") == 0)
10778             {
10779               if(ndim == 3)
10780                 sscanf(colon, "%f %f %f", &xsize, &ysize, &zsize);
10781               else
10782                 sscanf(colon, "%f %f %f %f",
10783                        &xsize, &ysize, &zsize, &dummy_size);
10784               xsize *= 10.0;
10785               ysize *= 10.0;
10786               zsize *= 10.0;
10787             }
10788           else if(strcmp(line, "sdtOrient") == 0)
10789             {
10790               while(isspace((int)*colon))
10791                 colon++;
10792               if(strncmp(colon, "sag", 3) == 0)
10793                 orientation = MRI_SAGITTAL;
10794               else if(strncmp(colon, "ax", 2) == 0)
10795                 orientation = MRI_HORIZONTAL;
10796               else if(strncmp(colon, "cor", 3) == 0)
10797                 orientation = MRI_CORONAL;
10798               else
10799                 {
10800                   fclose(fp);
10801                   errno = 0;
10802                   ErrorReturn
10803                     (NULL,
10804                      (ERROR_BADFILE,
10805                       "sdtRead(%s): unknown orientation %s\n", fname, colon));
10806                 }
10807             }
10808           else
10809             {
10810             }
10811         }
10812     }
10813 
10814   fclose(fp);
10815 
10816   if(data_type == -1)
10817     {
10818       errno = 0;
10819       ErrorReturn
10820         (NULL, (ERROR_BADFILE, "sdtRead(%s): data type undefined\n", fname));
10821     }
10822   if(dim[0] == -1 || dim[1] == -1 || dim[2] == -1)
10823     {
10824       errno = 0;
10825       ErrorReturn
10826         (NULL,
10827          (ERROR_BADFILE,
10828           "sdtRead(%s): one or more dimensions undefined\n", fname));
10829     }
10830 
10831   if(read_volume)
10832     {
10833       if((fp = fopen(fname, "r")) == NULL)
10834         {
10835           errno = 0;
10836           ErrorReturn
10837             (NULL,
10838              (ERROR_BADFILE,
10839               "sdtRead(%s): error opening data file %s\n", fname, fname));
10840         }
10841 
10842       mri = MRIreadRaw(fp, dim[0], dim[1], dim[2], data_type);
10843 
10844       if(mri == NULL)
10845         return(NULL);
10846 
10847       fclose(fp);
10848 
10849     }
10850   else
10851     {
10852       mri = MRIallocHeader(dim[0], dim[1], dim[2], data_type);
10853       if(mri == NULL)
10854         return(NULL);
10855     }
10856 
10857   mri->xsize = xsize;
10858   mri->ysize = ysize;
10859   mri->zsize = zsize;
10860 
10861   setDirectionCosine(mri, orientation);
10862 
10863   mri->thick = mri->zsize;
10864   mri->xend = mri->xsize * mri->width / 2.;
10865   mri->yend = mri->ysize * mri->height / 2.;
10866   mri->zend = mri->zsize * mri->depth / 2.;
10867   mri->xstart = -mri->xend;
10868   mri->ystart = -mri->yend;
10869   mri->zstart = -mri->zend;
10870 
10871   mri->imnr0 = 1;
10872   mri->imnr1 = dim[2];
10873 
10874   mri->ps = 1.0 /*0.001*/;
10875   mri->tr = 0 ;
10876   mri->te = 0 ;
10877   mri->ti = 0 ;
10878 
10879   strcpy(mri->fname, fname) ;
10880 
10881   return(mri);
10882 
10883 } /* end sdtRead() */
10884 
10885 MRI *MRIreadRaw(FILE *fp, int width, int height, int depth, int type)
10886 {
10887   MRI     *mri ;
10888   BUFTYPE *buf ;
10889   int     slice, pixels ;
10890   int     i;
10891 
10892   mri = MRIalloc(width, height, depth, type) ;
10893   if (!mri)
10894     return(NULL) ;
10895 
10896   pixels = width*height ;
10897   buf = (BUFTYPE *)calloc(pixels, data_size[type]) ;
10898 
10899   /* every width x height pixels should be another slice */
10900   for (slice = 0 ; slice < depth ; slice++)
10901     {
10902       if (fread(buf, data_size[type], pixels, fp) != pixels)
10903         {
10904           errno = 0;
10905           ErrorReturn(NULL,
10906                       (ERROR_BADFILE, "%s: could not read %dth slice (%d)",
10907                        Progname, slice, pixels)) ;
10908         }
10909       if(type == 0)
10910         local_buffer_to_image(buf, mri, slice, 0) ;
10911       if(type == 1)
10912         {
10913           for(i = 0;i < pixels;i++)
10914             ((int *)buf)[i] = orderIntBytes(((int *)buf)[i]);
10915           int_local_buffer_to_image((int *)buf, mri, slice, 0);
10916         }
10917       if(type == 2)
10918         {
10919           for(i = 0;i < pixels;i++)
10920             ((long32 *)buf)[i] = orderLong32Bytes(((long32 *)buf)[i]);
10921           long32_local_buffer_to_image((long32 *)buf, mri, slice, 0);
10922         }
10923       if(type == 3)
10924         {
10925           for(i = 0;i < pixels;i++)
10926             ((float *)buf)[i] = orderFloatBytes(((float *)buf)[i]);
10927           float_local_buffer_to_image((float *)buf, mri, slice, 0);
10928         }
10929       if(type == 4)
10930         {
10931           for(i = 0;i < pixels;i++)
10932             ((short *)buf)[i] = orderShortBytes(((short *)buf)[i]);
10933           short_local_buffer_to_image((short *)buf, mri, slice, 0);
10934         }
10935     }
10936 
10937   MRIinitHeader(mri) ;
10938   free(buf) ;
10939   return(mri) ;
10940 }
10941 
10942 static void
10943 int_local_buffer_to_image(int *buf, MRI *mri, int slice, int frame)
10944 {
10945   int           y, width, height ;
10946   int           *pslice ;
10947 
10948   width = mri->width ;
10949   height = mri->height ;
10950   for (y = 0 ; y < height ; y++)
10951     {
10952       pslice = &MRIIseq_vox(mri, 0, y, slice, frame) ;
10953       memcpy(pslice, buf, width*sizeof(int)) ;
10954       buf += width ;
10955     }
10956 }
10957 
10958 #if 0
10959 static void
10960 image_to_int_buffer(int *buf, MRI *mri, int slice)
10961 {
10962   int y, x, width, height, depth ;
10963 
10964   width = mri->width ;
10965   height = mri->height ;
10966   depth = mri->depth;
10967   for (y=0; y < height ; y++)
10968     {
10969       if(mri->type == MRI_UCHAR)
10970         {
10971           for(x = 0;x < depth;x++)
10972             buf[x] = (int)MRIvox(mri, x, y, slice);
10973         }
10974       else if(mri->type == MRI_SHORT)
10975         {
10976           for(x = 0;x < depth;x++)
10977             buf[x] = (int)MRISvox(mri, x, y, slice);
10978         }
10979       else if(mri->type == MRI_LONG)
10980         {
10981           for(x = 0;x < depth;x++)
10982             buf[x] = (int)MRILvox(mri, x, y, slice);
10983         }
10984       else if(mri->type == MRI_FLOAT)
10985         {
10986           for(x = 0;x < depth;x++)
10987             buf[x] = (int)MRIFvox(mri, x, y, slice);
10988         }
10989       else
10990         {
10991           memcpy(buf, mri->slices[slice][y], width*sizeof(int)) ;
10992         }
10993 
10994       buf += width ;
10995     }
10996 }
10997 static void
10998 image_to_long_buffer(long *buf, MRI *mri, int slice)
10999 {
11000   int y, x, width, height, depth ;
11001 
11002   width = mri->width ;
11003   height = mri->height ;
11004   depth = mri->depth;
11005   for (y=0; y < height ; y++)
11006     {
11007       if(mri->type == MRI_UCHAR)
11008         {
11009           for(x = 0;x < depth;x++)
11010             buf[x] = (long)MRIvox(mri, x, y, slice);
11011         }
11012       else if(mri->type == MRI_INT)
11013         {
11014           for(x = 0;x < depth;x++)
11015             buf[x] = (long)MRIIvox(mri, x, y, slice);
11016         }
11017       else if(mri->type == MRI_SHORT)
11018         {
11019           for(x = 0;x < depth;x++)
11020             buf[x] = (long)MRISvox(mri, x, y, slice);
11021         }
11022       else if(mri->type == MRI_FLOAT)
11023         {
11024           for(x = 0;x < depth;x++)
11025             buf[x] = (long)MRIFvox(mri, x, y, slice);
11026         }
11027       else
11028         {
11029           memcpy(buf, mri->slices[slice][y], width*sizeof(long)) ;
11030         }
11031 
11032       buf += width ;
11033     }
11034 }
11035 static void
11036 image_to_float_buffer(float *buf, MRI *mri, int slice)
11037 {
11038   int y, x, width, height, depth ;
11039 
11040   width = mri->width ;
11041   height = mri->height ;
11042   depth = mri->depth;
11043   for (y=0; y < height ; y++)
11044     {
11045       if(mri->type == MRI_UCHAR)
11046         {
11047           for(x = 0;x < depth;x++)
11048             buf[x] = (float)MRIvox(mri, x, y, slice);
11049         }
11050       else if(mri->type == MRI_INT)
11051         {
11052           for(x = 0;x < depth;x++)
11053             buf[x] = (float)MRIIvox(mri, x, y, slice);
11054         }
11055       else if(mri->type == MRI_LONG)
11056         {
11057           for(x = 0;x < depth;x++)
11058             buf[x] = (float)MRILvox(mri, x, y, slice);
11059         }
11060       else if(mri->type == MRI_SHORT)
11061         {
11062           for(x = 0;x < depth;x++)
11063             buf[x] = (float)MRISvox(mri, x, y, slice);
11064         }
11065       else
11066         {
11067           memcpy(buf, mri->slices[slice][y], width*sizeof(float)) ;
11068         }
11069 
11070       buf += width ;
11071     }
11072 }
11073 #endif
11074 
11075 static void
11076 long32_local_buffer_to_image(long32 *buf, MRI *mri, int slice, int frame)
11077 {
11078   int           y, width, height ;
11079   long32          *pslice ;
11080 
11081   width = mri->width ;
11082   height = mri->height ;
11083   for (y = 0 ; y < height ; y++)
11084     {
11085       pslice = &MRILseq_vox(mri, 0, y, slice, frame) ;
11086       memcpy(pslice, buf, width*sizeof(long)) ;
11087       buf += width ;
11088     }
11089 }
11090 
11091 
11092 static void
11093 float_local_buffer_to_image(float *buf, MRI *mri, int slice, int frame)
11094 {
11095   int           y, width, height ;
11096   float         *pslice ;
11097 
11098   width = mri->width ;
11099   height = mri->height ;
11100   for (y = 0 ; y < height ; y++)
11101     {
11102       pslice = &MRIFseq_vox(mri, 0, y, slice, frame) ;
11103       memcpy(pslice, buf, width*sizeof(float)) ;
11104       buf += width ;
11105     }
11106 }
11107 
11108 static void
11109 short_local_buffer_to_image(short *buf, MRI *mri, int slice, int frame)
11110 {
11111   int           y, width, height ;
11112   short         *pslice ;
11113 
11114   width = mri->width ;
11115   height = mri->height ;
11116   for (y = 0 ; y < height ; y++)
11117     {
11118       pslice = &MRISseq_vox(mri, 0, y, slice, frame) ;
11119       memcpy(pslice, buf, width*sizeof(short)) ;
11120       buf += width ;
11121     }
11122 }
11123 
11124 static void
11125 local_buffer_to_image(BUFTYPE *buf, MRI *mri, int slice, int frame)
11126 {
11127   int           y, width, height ;
11128   BUFTYPE       *pslice ;
11129 
11130   width = mri->width ;
11131   height = mri->height ;
11132   for (y = 0 ; y < height ; y++)
11133     {
11134       pslice = &MRIseq_vox(mri, 0, y, slice, frame) ;
11135       memcpy(pslice, buf, width*sizeof(BUFTYPE)) ;
11136       buf += width ;
11137     }
11138 }
11139 
11140 #define UNUSED_SPACE_SIZE 256
11141 #define USED_SPACE_SIZE   (3*sizeof(float)+4*3*sizeof(float))
11142 
11143 #define MGH_VERSION       1
11144 
11145 // declare function pointer
11146 static int (*myclose)(FILE *stream);
11147 
11148 static MRI *
11149 mghRead(char *fname, int read_volume, int frame)
11150 {
11151   MRI  *mri ;
11152   FILE  *fp = 0;
11153   int   start_frame, end_frame, width, height, depth, nframes, type, x, y, z,
11154     bpv, dof, bytes, version, ival, unused_space_size, good_ras_flag, i ;
11155   BUFTYPE *buf ;
11156   char   unused_buf[UNUSED_SPACE_SIZE+1] ;
11157   float  fval, xsize, ysize, zsize, x_r, x_a, x_s, y_r, y_a, y_s,
11158     z_r, z_a, z_s, c_r, c_a, c_s ;
11159   short  sval ;
11160   //  int tag_data_size;
11161   char *ext;
11162   int gzipped=0;
11163   char command[STRLEN];
11164   int nread;
11165   int tag;
11166 
11167   ext = strrchr(fname, '.') ;
11168   if (ext){
11169     ++ext;
11170     // if mgz, then it is compressed
11171     if (!stricmp(ext, "mgz") || strstr(fname, "mgh.gz")){
11172       gzipped = 1;
11173       myclose = pclose;  // assign function pointer for closing
11174 #ifdef Darwin
11175       // zcat on Max OS always appends and assumes a .Z extention,
11176       // whereas we want .m3z
11177       strcpy(command, "gunzip -c ");
11178 #else
11179       strcpy(command, "zcat ");
11180 #endif
11181       strcat(command, fname);
11182 
11183       errno = 0;
11184       fp = popen(command, "r");
11185       if (!fp){
11186         errno = 0;
11187         ErrorReturn(NULL, (ERROR_BADPARM,
11188                            "mghRead: encountered error executing: '%s'"
11189                            ",frame %d",
11190                            command,frame)) ;
11191       }
11192       if (errno){
11193         pclose(fp);
11194         errno = 0;
11195         ErrorReturn(NULL, (ERROR_BADPARM,
11196                            "mghRead: encountered error executing: '%s'"
11197                            ",frame %d",
11198                            command,frame)) ;
11199       }
11200     }
11201     else if (!stricmp(ext, "mgh")){
11202       myclose = fclose; // assign function pointer for closing
11203       fp = fopen(fname, "rb") ;
11204       if (!fp)
11205         {
11206           errno = 0;
11207           ErrorReturn
11208             (NULL,
11209              (ERROR_BADPARM,
11210               "mghRead(%s, %d): could not open file",
11211               fname, frame)) ;
11212         }
11213     }
11214   }
11215 
11216   /* keep the compiler quiet */
11217   xsize = ysize = zsize = 0;
11218   x_r = x_a = x_s = 0;
11219   y_r = y_a = y_s = 0;
11220   z_r = z_a = z_s = 0;
11221   c_r = c_a = c_s = 0;
11222 
11223   nread = freadIntEx(&version, fp) ;
11224   if (!nread)
11225     ErrorReturn(NULL, (ERROR_BADPARM,"mghRead(%s, %d): read error",
11226                        fname, frame)) ;
11227 
11228   width = freadInt(fp) ;
11229   height = freadInt(fp) ;
11230   depth =  freadInt(fp) ;
11231   nframes = freadInt(fp) ;
11232   type = freadInt(fp) ;
11233   dof = freadInt(fp) ;
11234 
11235   unused_space_size = UNUSED_SPACE_SIZE-sizeof(short) ;
11236 
11237   good_ras_flag = freadShort(fp) ;
11238   if (good_ras_flag > 0){     /* has RAS and voxel size info */
11239     unused_space_size -= USED_SPACE_SIZE ;
11240     xsize = freadFloat(fp) ;
11241     ysize = freadFloat(fp) ;
11242     zsize = freadFloat(fp) ;
11243 
11244     x_r = freadFloat(fp) ; x_a = freadFloat(fp) ; x_s = freadFloat(fp) ;
11245     y_r = freadFloat(fp) ; y_a = freadFloat(fp) ; y_s = freadFloat(fp) ;
11246 
11247     z_r = freadFloat(fp) ; z_a = freadFloat(fp) ; z_s = freadFloat(fp) ;
11248     c_r = freadFloat(fp) ; c_a = freadFloat(fp) ; c_s = freadFloat(fp) ;
11249   }
11250   /* so stuff can be added to the header in the future */
11251   fread(unused_buf, sizeof(char), unused_space_size, fp) ;
11252 
11253   switch (type){
11254   default:
11255   case MRI_FLOAT:  bpv = sizeof(float) ; break ;
11256   case MRI_UCHAR:  bpv = sizeof(char)  ; break ;
11257   case MRI_SHORT:  bpv = sizeof(short) ; break ;
11258   case MRI_INT:    bpv = sizeof(int) ; break ;
11259   case MRI_TENSOR:  bpv = sizeof(float) ; nframes = 9 ; break ;
11260   }
11261   bytes = width * height * bpv ;  /* bytes per slice */
11262   if(!read_volume){
11263     mri = MRIallocHeader(width, height, depth, type) ;
11264     mri->dof = dof ; mri->nframes = nframes ;
11265     if(gzipped){ // pipe cannot seek
11266       int count;
11267       for (count=0; count < mri->nframes*width*height*depth*bpv; count++)
11268         fgetc(fp);
11269     }
11270     else
11271       fseek(fp, mri->nframes*width*height*depth*bpv, SEEK_CUR) ;
11272   }
11273   else{
11274     if (frame >= 0) {
11275       start_frame = end_frame = frame ;
11276       if (gzipped){ // pipe cannot seek
11277         int count;
11278         for (count=0; count < frame*width*height*depth*bpv; count++)
11279           fgetc(fp);
11280       }
11281       else
11282         fseek(fp, frame*width*height*depth*bpv, SEEK_CUR) ;
11283       nframes = 1 ;
11284     }
11285     else{  /* hack - # of frames < -1 means to only read in that
11286               many frames. Otherwise I would have had to change the whole
11287               MRIread interface and that was too much of a pain. Sorry.
11288            */
11289       if (frame < -1)
11290         nframes = frame*-1 ;
11291 
11292       start_frame = 0 ; end_frame = nframes-1 ;
11293       if (Gdiag & DIAG_SHOW && DIAG_VERBOSE_ON)
11294         fprintf(stderr, "read %d frames\n", nframes);
11295     }
11296     buf = (BUFTYPE *)calloc(bytes, sizeof(BUFTYPE)) ;
11297     mri = MRIallocSequence(width, height, depth, type, nframes) ;
11298     mri->dof = dof ;
11299     for (frame = start_frame ; frame <= end_frame ; frame++){
11300       for (z = 0 ; z < depth ; z++){
11301         if (fread(buf, sizeof(char), bytes, fp) != bytes){
11302           // fclose(fp) ;
11303           myclose(fp);
11304           free(buf) ;
11305           ErrorReturn
11306             (NULL,
11307              (ERROR_BADFILE,
11308               "mghRead(%s): could not read %d bytes at slice %d",
11309               fname, bytes, z)) ;
11310         }
11311         switch (type)
11312           {
11313           case MRI_INT:
11314             for (i = y = 0 ; y < height ; y++)
11315               {
11316                 for (x = 0 ; x < width ; x++, i++)
11317                   {
11318                     ival = orderIntBytes(((int *)buf)[i]) ;
11319                     MRIIseq_vox(mri,x,y,z,frame-start_frame) = ival ;
11320                   }
11321               }
11322             break ;
11323           case MRI_SHORT:
11324             for (i = y = 0 ; y < height ; y++)
11325               {
11326                 for (x = 0 ; x < width ; x++, i++)
11327                   {
11328                     sval = orderShortBytes(((short *)buf)[i]) ;
11329                     MRISseq_vox(mri,x,y,z,frame-start_frame) = sval ;
11330                   }
11331               }
11332             break ;
11333           case MRI_TENSOR:
11334           case MRI_FLOAT:
11335             for (i = y = 0 ; y < height ; y++)
11336               {
11337                 for (x = 0 ; x < width ; x++, i++)
11338                   {
11339                     fval = orderFloatBytes(((float *)buf)[i]) ;
11340                     MRIFseq_vox(mri,x,y,z,frame-start_frame) = fval ;
11341                   }
11342               }
11343             break ;
11344           case MRI_UCHAR:
11345             local_buffer_to_image(buf, mri, z, frame-start_frame) ;
11346             break ;
11347           default:
11348             errno = 0;
11349             ErrorReturn(NULL,
11350                         (ERROR_UNSUPPORTED, "mghRead: unsupported type %d",
11351                          mri->type)) ;
11352             break ;
11353           }
11354       }
11355     }
11356     if (buf) free(buf) ;
11357   }
11358 
11359   if(good_ras_flag > 0){
11360     mri->xsize =     xsize ;
11361     mri->ysize =     ysize ;
11362     mri->zsize =     zsize ;
11363 
11364     mri->x_r = x_r  ;
11365     mri->x_a = x_a  ;
11366     mri->x_s = x_s  ;
11367 
11368     mri->y_r = y_r  ;
11369     mri->y_a = y_a  ;
11370     mri->y_s = y_s  ;
11371 
11372     mri->z_r = z_r  ;
11373     mri->z_a = z_a  ;
11374     mri->z_s = z_s  ;
11375 
11376     mri->c_r = c_r  ;
11377     mri->c_a = c_a  ;
11378     mri->c_s = c_s  ;
11379     if (good_ras_flag > 0)
11380       mri->ras_good_flag = 1 ;
11381   }
11382   else{
11383     fprintf
11384       (stderr,
11385        "-----------------------------------------------------------------\n"
11386        "Could not find the direction cosine information.\n"
11387        "Will use the CORONAL orientation.\n"
11388        "If not suitable, please provide the information in %s.\n"
11389        "-----------------------------------------------------------------\n",
11390        fname
11391        );
11392     setDirectionCosine(mri, MRI_CORONAL);
11393   }
11394   // read TR, Flip, TE, TI, FOV
11395   if (freadFloatEx(&(mri->tr), fp)){
11396     if (freadFloatEx(&fval, fp))
11397       {
11398         mri->flip_angle = fval;
11399         // flip_angle is double. I cannot use the same trick.
11400         if (freadFloatEx(&(mri->te), fp))
11401           if (freadFloatEx(&(mri->ti), fp))
11402             if (freadFloatEx(&(mri->fov), fp))
11403               ;
11404       }
11405   }
11406   // tag reading
11407   {
11408     long long len ;
11409     char *fnamedir;
11410 
11411     while ((tag = TAGreadStart(fp, &len)) != 0){
11412       switch (tag){
11413       case TAG_OLD_MGH_XFORM:
11414       case TAG_MGH_XFORM:
11415         fgets(mri->transform_fname, len+1, fp);
11416         // if this file exists then read the transform
11417         if(!FileExists(mri->transform_fname)){
11418           printf("  Talairach transform %s does not exist ...\n",
11419                  mri->transform_fname);
11420           fnamedir = fio_dirname(fname);
11421           sprintf(mri->transform_fname,"%s/transforms/talairach.xfm",fnamedir);
11422           printf("   ... trying %s ...",mri->transform_fname);
11423           if(FileExists(mri->transform_fname)) printf("which does exist ");
11424           else                                 printf("which does not exist ");
11425           printf("\n");
11426           free(fnamedir);
11427         }
11428         if(FileExists(mri->transform_fname)){
11429           // copied from corRead()
11430           if(input_transform_file
11431              (mri->transform_fname, &(mri->transform)) == NO_ERROR){
11432             mri->linear_transform = get_linear_transform_ptr(&mri->transform);
11433             mri->inverse_linear_transform =
11434               get_inverse_linear_transform_ptr(&mri->transform);
11435             mri->free_transform = 1;
11436             if (DIAG_VERBOSE_ON)
11437               fprintf
11438                 (stderr,
11439                  "INFO: loaded talairach xform : %s\n", mri->transform_fname);
11440           }
11441           else{
11442             errno = 0;
11443             ErrorPrintf
11444               (ERROR_BAD_FILE,
11445                "error loading transform from %s",mri->transform_fname);
11446             mri->linear_transform = NULL;
11447             mri->inverse_linear_transform = NULL;
11448             mri->free_transform = 1;
11449             (mri->transform_fname)[0] = '\0';
11450           }
11451         }
11452         else{
11453           fprintf(stderr,
11454                   "Can't find the talairach xform '%s'\n",
11455                   mri->transform_fname);
11456           fprintf(stderr, "Transform is not loaded into mri\n");
11457         }
11458         break ;
11459       case TAG_CMDLINE:
11460         if (mri->ncmds > MAX_CMDS)
11461           ErrorExit(ERROR_NOMEMORY,
11462                     "mghRead(%s): too many commands (%d) in file",
11463                     fname,mri->ncmds);
11464         mri->cmdlines[mri->ncmds] = calloc(len+1, sizeof(char)) ;
11465         fread(mri->cmdlines[mri->ncmds], sizeof(char), len, fp) ;
11466         mri->cmdlines[mri->ncmds][len] = 0 ;
11467         mri->ncmds++ ;
11468         break ;
11469       default:
11470         TAGskip(fp, tag, (long long)len) ;
11471         break ;
11472       }
11473     }
11474   }
11475 
11476 
11477   // fclose(fp) ;
11478   myclose(fp);
11479 
11480   // xstart, xend, ystart, yend, zstart, zend are not stored
11481   mri->xstart = - mri->width/2.*mri->xsize;
11482   mri->xend = mri->width/2. * mri->xsize;
11483   mri->ystart = - mri->height/2.*mri->ysize;
11484   mri->yend = mri->height/2.*mri->ysize;
11485   mri->zstart = - mri->depth/2.*mri->zsize;
11486   mri->zend = mri->depth/2.*mri->zsize;
11487   strcpy(mri->fname, fname);
11488   return(mri) ;
11489 }
11490 
11491 static int
11492 mghWrite(MRI *mri, char *fname, int frame)
11493 {
11494   FILE  *fp =0;
11495   int   ival, start_frame, end_frame, x, y, z, width, height, depth,
11496     unused_space_size, flen ;
11497   char  buf[UNUSED_SPACE_SIZE+1] ;
11498   float fval ;
11499   short sval ;
11500   int gzipped = 0;
11501   char *ext;
11502 
11503   if (frame >= 0)
11504     start_frame = end_frame = frame ;
11505   else
11506     {
11507       start_frame = 0 ; end_frame = mri->nframes-1 ;
11508     }
11509   ////////////////////////////////////////////////////////////
11510   ext = strrchr(fname, '.') ;
11511   if (ext)
11512     {
11513       char command[STRLEN];
11514       ++ext;
11515       // if mgz, then it is compressed
11516       if (!stricmp(ext, "mgz") || strstr(fname, "mgh.gz"))
11517         {
11518           // route stdout to a file
11519           gzipped = 1;
11520           myclose = pclose; // assign function pointer for closing
11521           // pipe writeto "gzip" open
11522           // pipe can executed under shell and thus understands >
11523           strcpy(command, "gzip -f -c > ");
11524           strcat(command, fname);
11525           errno = 0;
11526           fp = popen(command, "w");
11527           if (!fp)
11528             {
11529               errno = 0;
11530               ErrorReturn
11531                 (ERROR_BADPARM,
11532                  (ERROR_BADPARM,"mghWrite(%s, %d): could not open file",
11533                   fname, frame)) ;
11534             }
11535           if (errno)
11536             {
11537               pclose(fp);
11538               errno = 0;
11539               ErrorReturn
11540                 (ERROR_BADPARM,
11541                  (ERROR_BADPARM,"mghWrite(%s, %d): gzip had error",
11542                   fname, frame)) ;
11543             }
11544         }
11545       else if (!stricmp(ext, "mgh"))
11546         {
11547           fp = fopen(fname, "wb") ;
11548           myclose = fclose; // assign function pointer for closing
11549           if (!fp)
11550             {
11551               errno = 0;
11552               ErrorReturn
11553                 (ERROR_BADPARM,
11554                  (ERROR_BADPARM,"mghWrite(%s, %d): could not open file",
11555                   fname, frame)) ;
11556             }
11557         }
11558     }
11559   else
11560     {
11561       errno = 0;
11562       ErrorReturn(ERROR_BADPARM,
11563                   (ERROR_BADPARM,"mghWrite: filename '%s' "
11564                    "needs to have an extension of .mgh or .mgz",
11565                    fname)) ;
11566     }
11567 
11568   // sanity-check: make sure a file pointer was assigned
11569   if (fp==0)
11570     {
11571       errno = 0;
11572       ErrorReturn
11573         (ERROR_BADPARM,
11574          (ERROR_BADPARM,"mghWrite(%s, %d): could not open file: fp==0",
11575           fname, frame)) ;
11576     }
11577 
11578   /* WARNING - adding or removing anything before nframes will
11579      cause mghAppend to fail.
11580   */
11581   width = mri->width ; height = mri->height ; depth = mri->depth ;
11582   fwriteInt(MGH_VERSION, fp) ;
11583   fwriteInt(mri->width, fp) ;
11584   fwriteInt(mri->height, fp) ;
11585   fwriteInt(mri->depth, fp) ;
11586   fwriteInt(mri->nframes, fp) ;
11587   fwriteInt(mri->type, fp) ;
11588   fwriteInt(mri->dof, fp) ;
11589 
11590   unused_space_size = UNUSED_SPACE_SIZE - USED_SPACE_SIZE - sizeof(short) ;
11591 
11592   /* write RAS and voxel size info */
11593   fwriteShort(mri->ras_good_flag ? 1 : -1, fp) ;
11594   fwriteFloat(mri->xsize, fp) ;
11595   fwriteFloat(mri->ysize, fp) ;
11596   fwriteFloat(mri->zsize, fp) ;
11597 
11598   fwriteFloat(mri->x_r, fp) ;
11599   fwriteFloat(mri->x_a, fp) ;
11600   fwriteFloat(mri->x_s, fp) ;
11601 
11602   fwriteFloat(mri->y_r, fp) ;
11603   fwriteFloat(mri->y_a, fp) ;
11604   fwriteFloat(mri->y_s, fp) ;
11605 
11606   fwriteFloat(mri->z_r, fp) ;
11607   fwriteFloat(mri->z_a, fp) ;
11608   fwriteFloat(mri->z_s, fp) ;
11609 
11610   fwriteFloat(mri->c_r, fp) ;
11611   fwriteFloat(mri->c_a, fp) ;
11612   fwriteFloat(mri->c_s, fp) ;
11613 
11614   /* so stuff can be added to the header in the future */
11615   memset(buf, 0, UNUSED_SPACE_SIZE*sizeof(char)) ;
11616   fwrite(buf, sizeof(char), unused_space_size, fp) ;
11617 
11618   for (frame = start_frame ; frame <= end_frame ; frame++)
11619     {
11620       for (z = 0 ; z < depth ; z++)
11621         {
11622           for (y = 0 ; y < height ; y++)
11623             {
11624               switch (mri->type)
11625                 {
11626                 case MRI_SHORT:
11627                   for (x = 0 ; x < width ; x++)
11628                     {
11629                       if (z == 74 && y == 16 && x == 53)
11630                         DiagBreak() ;
11631                       sval = MRISseq_vox(mri,x,y,z,frame) ;
11632                       fwriteShort(sval, fp) ;
11633                     }
11634                   break ;
11635                 case MRI_INT:
11636                   for (x = 0 ; x < width ; x++)
11637                     {
11638                       if (z == 74 && y == 16 && x == 53)
11639                         DiagBreak() ;
11640                       ival = MRIIseq_vox(mri,x,y,z,frame) ;
11641                       fwriteInt(ival, fp) ;
11642                     }
11643                   break ;
11644                 case MRI_FLOAT:
11645                   for (x = 0 ; x < width ; x++)
11646                     {
11647                       if (z == 74 && y == 16 && x == 53)
11648                         DiagBreak() ;
11649                       fval = MRIFseq_vox(mri,x,y,z,frame) ;
11650                       //if(x==10 && y == 0 && z == 0 && frame == 67)
11651                       // printf("MRIIO: %g\n",fval);
11652                       fwriteFloat(fval, fp) ;
11653                     }
11654                   break ;
11655                 case MRI_UCHAR:
11656                   if (fwrite(&MRIseq_vox(mri,0,y,z,frame),
11657                              sizeof(BUFTYPE), width, fp)
11658                       != width)
11659                     {
11660                       errno = 0;
11661                       ErrorReturn
11662                         (ERROR_BADFILE,
11663                          (ERROR_BADFILE,
11664                           "mghWrite: could not write %d bytes to %s",
11665                           width, fname)) ;
11666                     }
11667                   break ;
11668                 default:
11669                   errno = 0;
11670                   ErrorReturn
11671                     (ERROR_UNSUPPORTED,
11672                      (ERROR_UNSUPPORTED, "mghWrite: unsupported type %d",
11673                       mri->type)) ;
11674                   break ;
11675                 }
11676             }
11677         }
11678     }
11679 
11680   fwriteFloat(mri->tr, fp) ;
11681   fwriteFloat(mri->flip_angle, fp) ;
11682   fwriteFloat(mri->te, fp) ;
11683   fwriteFloat(mri->ti, fp) ;
11684   fwriteFloat(mri->fov, fp); // somebody forgot this
11685 
11686   // if mri->transform_fname has non-zero length
11687   // I write a tag with strlength and write it
11688   // I increase the tag_datasize with this amount
11689   if ((flen=strlen(mri->transform_fname))> 0)
11690     {
11691 #if 0
11692       fwriteInt(TAG_MGH_XFORM, fp);
11693       fwriteInt(flen+1, fp); // write the size + 1 (for null) of string
11694       fputs(mri->transform_fname, fp);
11695 #else
11696       TAGwrite(fp, TAG_MGH_XFORM, mri->transform_fname, flen+1) ;
11697 #endif
11698     }
11699   // If we have any saved tag data, write it.
11700   if( NULL != mri->tag_data ) {
11701     // Int is 32 bit on 32 bit and 64 bit os and thus it is safer
11702     fwriteInt(mri->tag_data_size, fp);
11703     fwrite( mri->tag_data, mri->tag_data_size, 1, fp );
11704   }
11705 
11706 
11707   // write other tags
11708   {
11709     int i ;
11710 
11711     for (i = 0 ; i < mri->ncmds ; i++)
11712       TAGwrite(fp, TAG_CMDLINE, mri->cmdlines[i], strlen(mri->cmdlines[i])+1) ;
11713   }
11714 
11715 
11716   // fclose(fp) ;
11717   myclose(fp);
11718 
11719   return(NO_ERROR) ;
11720 }
11721 
11722 
11723 MRI *
11724 MRIreorder(MRI *mri_src, MRI *mri_dst, int xdim, int ydim, int zdim)
11725 {
11726   // note that allowed xdim, ydim, zdim values are only +/- 1,2,3 only
11727   // xdim tells the original x-axis goes to which axis of the new, etc.
11728   int  width, height, depth, xs, ys, zs, xd, yd, zd, x, y, z, f ;
11729   float ras_sign;
11730 
11731   width = mri_src->width ; height = mri_src->height ; depth = mri_src->depth;
11732   if (!mri_dst)
11733     mri_dst = MRIclone(mri_src, NULL) ;
11734 
11735   /* check that the source ras coordinates are good and
11736      that each direction is used once and only once */
11737   if(mri_src->ras_good_flag)
11738     if(abs(xdim) * abs(ydim) * abs(zdim) != 6 ||
11739        abs(xdim) + abs(ydim) + abs(zdim) != 6)
11740       mri_dst->ras_good_flag = 0;
11741 
11742   xd = yd = zd = 0 ;
11743 
11744   ras_sign = (xdim < 0 ? -1.0 : 1.0);
11745   // check xdim direction size (XDIM=1, YDIM=2, ZDIM=3)
11746   // xdim tells original x-axis goes to where
11747   switch (abs(xdim))
11748     {
11749     default:
11750     case XDIM:
11751       if (mri_dst->width != width)
11752         {
11753           errno = 0;
11754           ErrorReturn(NULL,(ERROR_BADPARM, "MRIreorder: incorrect dst width"));
11755         }
11756       break ;
11757     case YDIM:
11758       if (mri_dst->height != width)
11759         {
11760           errno = 0;
11761           ErrorReturn(NULL,(ERROR_BADPARM, "MRIreorder: incorrect dst width"));
11762         }
11763       break ;
11764     case ZDIM:
11765       if (mri_dst->depth != width)
11766         {
11767           errno = 0;
11768           ErrorReturn(NULL,(ERROR_BADPARM, "MRIreorder: incorrect dst width"));
11769         }
11770       break ;
11771     }
11772   ras_sign = (ydim < 0 ? -1.0 : 1.0);
11773   // check ydim
11774   // ydim tells original y-axis goes to where
11775   switch (abs(ydim))
11776     {
11777     default:
11778     case XDIM:
11779       if (mri_dst->width != height)
11780         {
11781           errno = 0;
11782           ErrorReturn
11783             (NULL,(ERROR_BADPARM, "MRIreorder: incorrect dst height"));
11784         }
11785       break ;
11786     case YDIM:
11787       if (mri_dst->height != height)
11788         {
11789           errno = 0;
11790           ErrorReturn
11791             (NULL,(ERROR_BADPARM, "MRIreorder: incorrect dst height"));
11792         }
11793       break ;
11794     case ZDIM:
11795       if (mri_dst->depth != height)
11796         {
11797           errno = 0;
11798           ErrorReturn
11799             (NULL,(ERROR_BADPARM, "MRIreorder: incorrect dst height"));
11800         }
11801       break ;
11802     }
11803   ras_sign = (zdim < 0 ? -1.0 : 1.0);
11804   // check zdim
11805   // zdim tells original z-axis goes to where
11806   switch (abs(zdim))
11807     {
11808     default:
11809     case XDIM:
11810       if (mri_dst->width != depth)
11811         {
11812           errno = 0;
11813           ErrorReturn(NULL,(ERROR_BADPARM, "MRIreorder: incorrect dst depth"));
11814         }
11815       break ;
11816     case YDIM:
11817       if (mri_dst->height != depth)
11818         {
11819           errno = 0;
11820           ErrorReturn(NULL,(ERROR_BADPARM, "MRIreorder: incorrect dst depth"));
11821         }
11822       break ;
11823     case ZDIM:
11824       if (mri_dst->depth != depth)
11825         {
11826           errno = 0;
11827           ErrorReturn(NULL,(ERROR_BADPARM, "MRIreorder: incorrect dst depth"));
11828         }
11829       break ;
11830     }
11831 
11832   for(f = 0; f < mri_src->nframes; f++){
11833     for (zs = 0 ; zs < depth ; zs++)
11834       {
11835         if (zdim < 0) z = depth - zs - 1 ;
11836         else          z = zs ;
11837         switch (abs(zdim))
11838           {
11839           case XDIM:  xd = z ; break ;
11840           case YDIM:  yd = z ; break ;
11841           case ZDIM:
11842           default:    zd = z ; break ;
11843           }
11844         for (ys = 0 ; ys < height ; ys++)
11845           {
11846             if (ydim < 0) y = height - ys - 1 ;
11847             else          y = ys ;
11848             switch (abs(ydim))
11849               {
11850               case XDIM: xd = y ; break ;
11851               case YDIM: yd = y ; break ;
11852               case ZDIM:
11853               default: zd = y ; break ;
11854               }
11855             for (xs = 0 ; xs < width ; xs++)
11856               {
11857                 if (xdim < 0) x = width - xs - 1 ;
11858                 else          x = xs ;
11859                 switch (abs(xdim))
11860                   {
11861                   case XDIM: xd = x ; break ;
11862                   case YDIM: yd = x ; break ;
11863                   case ZDIM:
11864                   default:   zd = x ; break ;
11865                   }
11866                 switch (mri_src->type)
11867                   {
11868                   case MRI_SHORT:
11869                     MRISseq_vox(mri_dst,xd,yd,zd,f) =
11870                       MRISseq_vox(mri_src,xs,ys,zs,f) ;
11871                     break ;
11872                   case MRI_FLOAT:
11873                     MRIFseq_vox(mri_dst,xd,yd,zd,f) =
11874                       MRIFseq_vox(mri_src,xs,ys,zs,f);
11875                     break ;
11876                   case MRI_INT:
11877                     MRIIseq_vox(mri_dst,xd,yd,zd,f) =
11878                       MRIIseq_vox(mri_src,xs,ys,zs,f);
11879                     break ;
11880                   case MRI_UCHAR:
11881                     MRIseq_vox(mri_dst,xd,yd,zd,f)  =
11882                       MRIseq_vox(mri_src,xs,ys,zs,f);
11883                     break ;
11884                   default:
11885                     errno = 0;
11886                     ErrorReturn
11887                       (NULL,(ERROR_UNSUPPORTED,
11888                              "MRIreorder: unsupported voxel format %d",
11889                              mri_src->type)) ;
11890                     break ;
11891                   }
11892               }
11893           }
11894       }
11895   }/* end loop over frames */
11896   return(mri_dst) ;
11897 }
11898 
11899 /*-----------------------------------------------------
11900   Parameters:
11901 
11902   Returns value:
11903 
11904   Description
11905   Write the MRI header information to the file
11906   COR-.info in the directory specified by 'fpref'
11907   ------------------------------------------------------*/
11908 int
11909 MRIwriteInfo(MRI *mri, char *fpref)
11910 {
11911   FILE    *fp;
11912   char    fname[STRLEN];
11913   int     slice_direction;
11914   sprintf(fname,"%s/%s",fpref, INFO_FNAME);
11915   fp = fopen(fname,"w");
11916   if (fp == NULL)
11917     {
11918       errno = 0;
11919       ErrorReturn(ERROR_NO_FILE,
11920                   (ERROR_NO_FILE,
11921                    "MRIwriteInfo(%s): could not open %s.\n", fpref, fname)) ;
11922     }
11923 
11924   fprintf(fp, "%s %d\n", "imnr0", mri->imnr0);
11925   fprintf(fp, "%s %d\n", "imnr1", mri->imnr1);
11926   slice_direction = getSliceDirection(mri);
11927   fprintf(fp, "%s %d\n", "ptype",
11928           slice_direction == MRI_CORONAL ? 2 :
11929           slice_direction == MRI_HORIZONTAL ? 0 : 1) ;
11930   fprintf(fp, "%s %d\n", "x", mri->width);
11931   fprintf(fp, "%s %d\n", "y", mri->height);
11932   fprintf(fp, "%s %f\n", "fov", mri->fov/MM_PER_METER);
11933   fprintf(fp, "%s %f\n", "thick", mri->ps/MM_PER_METER);
11934   fprintf(fp, "%s %f\n", "psiz", mri->ps/MM_PER_METER);
11935   fprintf(fp, "%s %f\n", "locatn", mri->location); /* locatn */
11936   fprintf(fp, "%s %f\n", "strtx", mri->xstart/MM_PER_METER); /* strtx */
11937   fprintf(fp, "%s %f\n", "endx", mri->xend/MM_PER_METER); /* endx */
11938   fprintf(fp, "%s %f\n", "strty", mri->ystart/MM_PER_METER); /* strty */
11939   fprintf(fp, "%s %f\n", "endy", mri->yend/MM_PER_METER); /* endy */
11940   fprintf(fp, "%s %f\n", "strtz", mri->zstart/MM_PER_METER); /* strtz */
11941   fprintf(fp, "%s %f\n", "endz", mri->zend/MM_PER_METER); /* endz */
11942   fprintf(fp, "%s %f\n", "tr", mri->tr) ;
11943   fprintf(fp, "%s %f\n", "te", mri->te) ;
11944   fprintf(fp, "%s %f\n", "ti", mri->ti) ;
11945   if (mri->linear_transform)
11946     {
11947       char fname[STRLEN] ;
11948 
11949       /*
11950          this won't work for relative paths which are not the same for the
11951          destination directory as for the the source directory.
11952       */
11953       sprintf(fname,"%s", mri->transform_fname);
11954       fprintf(fp, "xform %s\n", fname) ;
11955 
11956 #if 0
11957       /* doesn't work - I don't know why */
11958       if (output_transform_file(fname, "talairach xfm", &mri->transform) != OK)
11959         {
11960           errno = 0;
11961           ErrorPrintf
11962             (ERROR_BADFILE, "MRIwriteInfo(%s): xform write failed",fpref);
11963         }
11964 #endif
11965 
11966     }
11967 
11968   fprintf(fp, "%s %d\n", "ras_good_flag", mri->ras_good_flag);
11969   fprintf(fp, "%s %f %f %f\n", "x_ras", mri->x_r, mri->x_a, mri->x_s);
11970   fprintf(fp, "%s %f %f %f\n", "y_ras", mri->y_r, mri->y_a, mri->y_s);
11971   fprintf(fp, "%s %f %f %f\n", "z_ras", mri->z_r, mri->z_a, mri->z_s);
11972   fprintf(fp, "%s %f %f %f\n", "c_ras", mri->c_r, mri->c_a, mri->c_s);
11973 
11974   fclose(fp);
11975 
11976   return(NO_ERROR) ;
11977 }
11978 
11979 /*-----------------------------------------------------
11980   Parameters:
11981 
11982   Returns value:
11983 
11984   Description
11985   Write an MRI header and a set of data files to
11986   the directory specified by 'fpref'
11987   ------------------------------------------------------*/
11988 int
11989 MRIappend(MRI *mri, char *fpref)
11990 {
11991   int      type, frame ;
11992   char     fname[STRLEN] ;
11993 
11994   MRIunpackFileName(fpref, &frame, &type, fname) ;
11995   if (type == MRI_MGH_FILE)
11996     return(mghAppend(mri, fname, frame)) ;
11997   else
11998     {
11999       errno = 0;
12000       ErrorReturn(ERROR_UNSUPPORTED,
12001                   (ERROR_UNSUPPORTED, "MRIappend(%s): file type not supported",
12002                    fname)) ;
12003     }
12004 
12005   return(NO_ERROR) ;
12006 }
12007 
12008 static int
12009 mghAppend(MRI *mri, char *fname, int frame)
12010 {
12011   FILE  *fp ;
12012   int   start_frame, end_frame, x, y, z, width, height, depth, nframes ;
12013 
12014   if (frame >= 0)
12015     start_frame = end_frame = frame ;
12016   else
12017     {
12018       start_frame = 0 ; end_frame = mri->nframes-1 ;
12019     }
12020   fp = fopen(fname, "rb") ;
12021   if (!fp)   /* doesn't exist */
12022     return(mghWrite(mri, fname, frame)) ;
12023   fclose(fp) ;
12024   fp = fopen(fname, "r+b") ;
12025   if (!fp)
12026     {
12027       errno = 0;
12028       ErrorReturn(ERROR_BADPARM,
12029                   (ERROR_BADPARM,"mghAppend(%s, %d): could not open file",
12030                    fname, frame)) ;
12031     }
12032 
12033   /* WARNING - this is dependent on the order of writing in mghWrite */
12034   width = mri->width ; height = mri->height ; depth = mri->depth ;
12035   fseek(fp, 4*sizeof(int), SEEK_SET) ;
12036   nframes = freadInt(fp) ;
12037   fseek(fp, 4*sizeof(int), SEEK_SET) ;
12038   fwriteInt(nframes+end_frame-start_frame+1, fp) ;
12039   fseek(fp, 0, SEEK_END) ;
12040 
12041   for (frame = start_frame ; frame <= end_frame ; frame++)
12042     {
12043       for (z = 0 ; z < depth ; z++)
12044         {
12045           for (y = 0 ; y < height ; y++)
12046             {
12047               switch (mri->type)
12048                 {
12049                 case MRI_FLOAT:
12050                   for (x = 0 ; x < width ; x++)
12051                     {
12052                       fwriteFloat(MRIFseq_vox(mri,x,y,z,frame), fp) ;
12053                     }
12054                   break ;
12055                 case MRI_UCHAR:
12056                   if (fwrite(&MRIseq_vox(mri,0,y,z,frame),
12057                              sizeof(BUFTYPE), width, fp)
12058                       != width)
12059                     {
12060                       errno = 0;
12061                       ErrorReturn
12062                         (ERROR_BADFILE,
12063                          (ERROR_BADFILE,
12064                           "mghAppend: could not write %d bytes to %s",
12065                           width, fname)) ;
12066                     }
12067                   break ;
12068                 default:
12069                   errno = 0;
12070                   ErrorReturn
12071                     (ERROR_UNSUPPORTED,
12072                      (ERROR_UNSUPPORTED, "mghAppend: unsupported type %d",
12073                       mri->type)) ;
12074                   break ;
12075                 }
12076             }
12077         }
12078     }
12079 
12080   fclose(fp) ;
12081   return(NO_ERROR) ;
12082 }
12083 
12084 /*-----------------------------------------------------
12085   Parameters:
12086 
12087   Returns value:
12088 
12089   Description
12090   ------------------------------------------------------*/
12091 int
12092 MRIunpackFileName(char *inFname, int *pframe, int *ptype, char *outFname)
12093 {
12094   char *number = NULL, *at = NULL, buf[STRLEN] ;
12095   struct stat stat_buf;
12096 
12097   strcpy(outFname, inFname) ;
12098   number = strrchr(outFname, '#') ;
12099   at = strrchr(outFname, '@');
12100 
12101   if(at)
12102     *at = '\0';
12103 
12104   if (number)   /* '#' in filename indicates frame # */
12105     {
12106       if (sscanf(number+1, "%d", pframe) < 1)
12107         *pframe = -1 ;
12108       *number = 0 ;
12109     }
12110   else
12111     *pframe = -1 ;
12112 
12113   if (at)
12114     {
12115       at = StrUpper(strcpy(buf, at+1)) ;
12116       if (!strcmp(at, "MNC"))
12117         *ptype = MRI_MINC_FILE ;
12118       else if (!strcmp(at, "MINC"))
12119         *ptype = MRI_MINC_FILE ;
12120       else if (!strcmp(at, "BRIK"))
12121         *ptype = BRIK_FILE ;
12122       else if (!strcmp(at, "SIEMENS"))
12123         *ptype = SIEMENS_FILE ;
12124       else if (!strcmp(at, "MGH"))
12125         *ptype = MRI_MGH_FILE ;
12126       else if (!strcmp(at, "MR"))
12127         *ptype = GENESIS_FILE ;
12128       else if (!strcmp(at, "GE"))
12129         *ptype = GE_LX_FILE ;
12130       else if (!strcmp(at, "IMG"))
12131         *ptype = MRI_ANALYZE_FILE ;
12132       else if (!strcmp(at, "COR"))
12133         *ptype = MRI_CORONAL_SLICE_DIRECTORY ;
12134       else if (!strcmp(at, "BSHORT"))
12135         *ptype = BSHORT_FILE;
12136       else if (!strcmp(at, "SDT"))
12137         *ptype = SDT_FILE;
12138       else
12139         {
12140           errno = 0;
12141           ErrorExit(ERROR_UNSUPPORTED, "unknown file type %s", at);
12142         }
12143     }
12144   else  /* no '@' found */
12145     {
12146 
12147       *ptype = -1;
12148 
12149 
12150       if(is_genesis(outFname))
12151         *ptype = GENESIS_FILE;
12152       else if(is_ge_lx(outFname))
12153         *ptype = GE_LX_FILE;
12154       else if(is_brik(outFname))
12155         *ptype = BRIK_FILE;
12156       else if(is_siemens(outFname))
12157         *ptype = SIEMENS_FILE;
12158       else if(is_analyze(outFname))
12159         *ptype = MRI_ANALYZE_FILE;
12160       else if (is_signa(outFname))
12161         *ptype = SIGNA_FILE ;
12162       else if(is_sdt(outFname))
12163         *ptype = SDT_FILE;
12164       else if(is_mgh(outFname))
12165         *ptype = MRI_MGH_FILE;
12166       else if(is_mnc(outFname))
12167         *ptype = MRI_MINC_FILE;
12168       else if(is_bshort(outFname))
12169         *ptype = BSHORT_FILE;
12170       else
12171         {
12172           if(stat(outFname, &stat_buf) < 0)
12173             {
12174               errno = 0;
12175               ErrorReturn
12176                 (ERROR_BADFILE,
12177                  (ERROR_BAD_FILE, "can't stat file %s", outFname));
12178             }
12179           if(S_ISDIR(stat_buf.st_mode))
12180             *ptype = MRI_CORONAL_SLICE_DIRECTORY;
12181         }
12182 
12183       if(*ptype == -1)
12184         {
12185           errno = 0;
12186           ErrorReturn
12187             (ERROR_BADPARM,
12188              (ERROR_BADPARM,
12189               "unrecognized file type for file %s", outFname));
12190         }
12191 
12192     }
12193 
12194   return(NO_ERROR) ;
12195 }
12196 
12197 /*---------------------------------------------------------------
12198   MRIwriteAnyFormat() - saves the data in the given mri structure to
12199   "any" format, where "any" is defined as anything writable by
12200   MRIwrite and wfile format. If wfile format is used, then mriframe
12201   must be a valid frame number. The val field of the surf is
12202   preserved. If another format is used, then, if mriframe = -1, then
12203   all frames are stored, otherwise the given frame is stored. If
12204   fmt is NULL, then it will attempt to infer the format from the
12205   name. surf only needs to be supplied when format is wfile. Legal
12206   formats include: wfile, paint, w, bshort, bfloat, COR, analyze,
12207   analyze4d, spm.
12208   ---------------------------------------------------------------*/
12209 int MRIwriteAnyFormat(MRI *mri, char *fileid, char *fmt,
12210                       int mriframe, MRIS *surf)
12211 {
12212   int fmtid, err, n, r, c, s;
12213   float *v=NULL,f;
12214   MRI *mritmp=NULL;
12215 
12216   if(fmt != NULL && (!strcmp(fmt,"paint") || !strcmp(fmt,"w") ||
12217                      !strcmp(fmt,"wfile")) ){
12218 
12219     /* Save as a wfile */
12220     if(surf == NULL){
12221       printf("ERROR: MRIwriteAnyFormat: need surf with paint format\n");
12222       return(1);
12223     }
12224     if(mriframe >= mri->nframes){
12225       printf("ERROR: MRIwriteAnyFormat: frame (%d) exceeds number of\n"
12226              "       frames\n",mriframe >= mri->nframes);
12227       return(1);
12228     }
12229 
12230     /* Copy current surf values into v (temp storage) */
12231     v = (float *)calloc(surf->nvertices,sizeof(float));
12232     for(n=0; n < surf->nvertices; n++) v[n] = surf->vertices[n].val;
12233 
12234     /* Copy the mri values into the surf values */
12235     err = MRIScopyMRI(surf, mri, mriframe, "val");
12236     if(err){
12237       printf("ERROR: MRIwriteAnyFormat: could not copy MRI to MRIS\n");
12238       return(1);
12239     }
12240 
12241     /* Write the surf values */
12242     err = MRISwriteValues(surf,fileid);
12243 
12244     /* Copy v back into surf values */
12245     for(n=0; n < surf->nvertices; n++) surf->vertices[n].val = v[n];
12246     free(v);
12247 
12248     /* Check for errors from write of values */
12249     if(err){
12250       printf("ERROR: MRIwriteAnyFormat: MRISwriteValues\n");
12251       return(1);
12252     }
12253 
12254     return(0);
12255   }
12256 
12257   /* Copy the desired frame if necessary */
12258   if(mriframe > -1){
12259     if(mriframe >= mri->nframes){
12260       printf("ERROR: MRIwriteAnyFormat: frame (%d) exceeds number of\n"
12261              "       frames\n",mriframe >= mri->nframes);
12262       return(1);
12263     }
12264     mritmp = MRIallocSequence(mri->width, mri->height, mri->depth,
12265                               mri->type, 1);
12266     for(c=0; c < mri->width; c++){
12267       for(r=0; r < mri->height; r++){
12268         for(s=0; s < mri->depth; s++){
12269           f = MRIgetVoxVal(mri, c, r, s, mriframe);
12270           MRIsetVoxVal(mritmp, c, r, s, 0, f);
12271         }
12272       }
12273     }
12274   }
12275   else mritmp = mri;
12276 
12277   /*------------ Save using MRIwrite or MRIwriteType ---------*/
12278   if(fmt != NULL){
12279     /* Save as the given format */
12280     fmtid = string_to_type(fmt);
12281     if(fmtid == MRI_VOLUME_TYPE_UNKNOWN){
12282       printf("ERROR: format string %s unrecognized\n",fmt);
12283       return(1);
12284     }
12285     err = MRIwriteType(mritmp,fileid,fmtid);
12286     if(err){
12287       printf("ERROR: MRIwriteAnyFormat: could not write to %s\n",fileid);
12288       return(1);
12289     }
12290   }
12291   else{
12292     /* Try to infer the type and save (format is NULL) */
12293     err = MRIwrite(mritmp,fileid);
12294     if(err){
12295       printf("ERROR: MRIwriteAnyFormat: could not write to %s\n",fileid);
12296       return(1);
12297     }
12298   }
12299 
12300   if(mri != mritmp) MRIfree(&mritmp);
12301 
12302   return(0);
12303 }
12304 
12305 
12306 
12307 /* EOF */
12308 
12309 
12310 /*-------------------------------------------------------------------*/
12311 /*-------------------------------------------------------------------*/
12312 /* ----------- Obsolete functions below. --------------*/
12313 /*-------------------------------------------------------------------*/
12314 /*-------------------------------------------------------------------*/
12315 
12316 
12317 #if 0
12318 /*-------------------------------------------------------------------
12319   bfloatWrite() - obsolete. Use bvolumeWrite.
12320   -------------------------------------------------------------------*/
12321 static int bfloatWrite(MRI *vol, char *stem)
12322 {
12323 
12324   int i, j, t;
12325   char fname[STRLEN];
12326   float *buf;
12327   FILE *fp;
12328   int result;
12329   MRI *mri = NULL;
12330   int dealloc;
12331   int nslices,nframes;
12332 
12333   if(vol->type != MRI_FLOAT){
12334     printf("INFO: bfloatWrite: changing type\n");
12335     nslices = vol->depth;
12336     nframes = vol->nframes;
12337     vol->depth = nslices*nframes;
12338     vol->nframes = 1;
12339     mri = MRIchangeType(vol,MRI_FLOAT,0,0,0);
12340     if(mri == NULL) {
12341       fprintf(stderr,"ERROR: bfloatWrite: MRIchangeType\n");
12342       return(1);
12343     }
12344     vol->depth = nslices;
12345     vol->nframes = nframes;
12346     mri->depth = nslices;
12347     mri->nframes = nframes;
12348     dealloc = 1;
12349   }
12350   else{
12351     mri = vol;
12352     dealloc = 0;
12353   }
12354 
12355   buf = (float *)malloc(mri->width * sizeof(float));
12356 
12357   for(i = 0;i < mri->depth;i++)
12358     {
12359       /* ----- write the header file ----- */
12360       sprintf(fname, "%s_%03d.hdr", stem, i);
12361       if((fp = fopen(fname, "w")) == NULL)
12362         {
12363           free(buf);
12364           errno = 0;
12365           ErrorReturn
12366             (ERROR_BADFILE,
12367              (ERROR_BADFILE,
12368               "bfloatWrite(): can't open file %s", fname));
12369         }
12370 #if (BYTE_ORDER == LITTLE_ENDIAN)
12371       fprintf(fp, "%d %d %d %d\n", mri->height, mri->width, mri->nframes, 1);
12372 #else
12373       fprintf(fp, "%d %d %d %d\n", mri->height, mri->width, mri->nframes, 0);
12374 #endif
12375       fclose(fp);
12376 
12377       /* ----- write the data file ----- */
12378       sprintf(fname, "%s_%03d.bfloat", stem, i);
12379       if((fp = fopen(fname, "w")) == NULL)
12380         {
12381           if(dealloc) MRIfree(&mri);
12382           free(buf);
12383           errno = 0;
12384           ErrorReturn
12385             (ERROR_BADFILE,
12386              (ERROR_BADFILE,
12387               "bfloatWrite(): can't open file %s", fname));
12388         }
12389 
12390       for(t = 0;t < mri->nframes;t++)
12391         {
12392           for(j = 0;j < mri->height;j++)
12393             {
12394               memcpy(buf, mri->slices[t*mri->depth + i][j],
12395                      mri->width * sizeof(float));
12396 #if 0
12397               /* this byte swapping routine does not seem to work */
12398               /* now uses endian flag in .hdr (above) */
12399               for(pos = 0; pos < mri->width * sizeof(float);
12400                   pos += sizeof(float))
12401                 {
12402                   c = (char *) (&(buf[pos]));
12403                   memcpy(&(swap_buf[0]), c, 4);
12404                   c[0] = swap_buf[3];
12405                   c[1] = swap_buf[2];
12406                   c[2] = swap_buf[1];
12407                   c[3] = swap_buf[0];
12408                 }
12409 #endif
12410               fwrite(buf, sizeof(float), mri->width, fp);
12411 
12412             }
12413 
12414         }
12415 
12416       fclose(fp);
12417 
12418     }
12419 
12420   free(buf);
12421 
12422   /* ----- write the bhdr file ----- */
12423   sprintf(fname, "%s.bhdr", stem);
12424   if((fp = fopen(fname, "w")) == NULL)
12425     {
12426       if(dealloc) MRIfree(&mri);
12427       errno = 0;
12428       ErrorReturn
12429         (ERROR_BADFILE,
12430          (ERROR_BADFILE,
12431           "bfloatWrite(): can't open file %s", fname));
12432     }
12433 
12434   result = write_bhdr(mri, fp);
12435 
12436   fclose(fp);
12437 
12438   if(dealloc) MRIfree(&mri);
12439   return(result);
12440 
12441 } /* end bfloatWrite() */
12442 
12443 /*-------------------------------------------------------------------
12444   bshortWrite() - obsolete. Use bvolumeWrite.
12445   -------------------------------------------------------------------*/
12446 static int bshortWrite(MRI *vol, char *fname_passed)
12447 {
12448 
12449   int i, j, t;
12450   char fname[STRLEN];
12451   short *buf;
12452   FILE *fp;
12453   int result;
12454   MRI *subject_info = NULL;
12455   char subject_volume_dir[STRLEN];
12456   char *subjects_dir;
12457   char *sn;
12458   char analyse_fname[STRLEN], register_fname[STRLEN];
12459   char output_dir[STRLEN];
12460   char *c;
12461   int od_length;
12462   char t1_path[STRLEN];
12463   MATRIX *cf, *bf, *ibf, *af, *iaf, *as, *bs, *cs, *ics, *r;
12464   MATRIX *r1, *r2, *r3, *r4;
12465   float det;
12466   int bad_flag;
12467   int l;
12468   char stem[STRLEN];
12469   char *c1, *c2, *c3;
12470   struct stat stat_buf;
12471   char subject_dir[STRLEN];
12472   int dealloc, nslices, nframes;
12473   MRI *mri;
12474   float min,max;
12475 
12476   if(vol->type != MRI_SHORT){
12477     printf("INFO: bshortWrite: changing type\n");
12478     nslices = vol->depth;
12479     nframes = vol->nframes;
12480     vol->depth = nslices*nframes;
12481     vol->nframes = 1;
12482     MRIlimits(vol,&min,&max);
12483     printf("INFO: bshortWrite: range %g %g\n",min,max);
12484     mri = MRIchangeType(vol,MRI_SHORT,min,max,1);
12485     if(mri == NULL) {
12486       fprintf(stderr,"ERROR: bshortWrite: MRIchangeType\n");
12487       return(1);
12488     }
12489     vol->depth = nslices;
12490     vol->nframes = nframes;
12491     mri->depth = nslices;
12492     mri->nframes = nframes;
12493     dealloc = 1;
12494   }
12495   else{
12496     mri = vol;
12497     dealloc = 0;
12498   }
12499 
12500   /* ----- get the stem from the passed file name ----- */
12501   /*
12502     four options:
12503     1. stem_xxx.bshort
12504     2. stem.bshort
12505     3. stem_xxx
12506     4. stem
12507     other possibles:
12508     stem_.bshort
12509   */
12510 
12511   l = strlen(fname_passed);
12512 
12513   c1 = fname_passed + l - 11;
12514   c2 = fname_passed + l - 7;
12515   c3 = fname_passed + l - 4;
12516 
12517   strcpy(stem, fname_passed);
12518 
12519   if(c1 > fname_passed)
12520     {
12521       if(*c1 == '_' && strcmp(c1+4, ".bshort") == 0)
12522         stem[(int)(c1-fname_passed)] = '\0';
12523     }
12524   if(c2 > fname_passed)
12525     {
12526       if(strcmp(c2, ".bshort") == 0)
12527         stem[(int)(c2-fname_passed)] = '\0';
12528     }
12529   if(c3 > fname_passed)
12530     {
12531       if(*c3 == '_')
12532         stem[(int)(c3-fname_passed)] = '\0';
12533     }
12534 
12535   c = strrchr(stem, '/');
12536   if(c == NULL)
12537     output_dir[0] = '\0';
12538   else
12539     {
12540       od_length = (int)(c - stem);
12541       strncpy(output_dir, stem, od_length);
12542       /* -- leaving the trailing '/' on a directory is not my
12543          usual convention, but here it's a load easier
12544          if there's no directory in stem... -ch -- */
12545       output_dir[od_length] = '/';
12546       output_dir[od_length+1] = '\0';
12547     }
12548 
12549   sprintf(analyse_fname, "%s%s", output_dir, "analyse.dat");
12550   sprintf(register_fname, "%s%s", output_dir, "register.dat");
12551 
12552   buf = (short *)malloc(mri->width * mri->height * sizeof(short));
12553 
12554   for(i = 0;i < mri->depth;i++)
12555     {
12556 
12557       /* ----- write the header file ----- */
12558       sprintf(fname, "%s_%03d.hdr", stem, i);
12559       if((fp = fopen(fname, "w")) == NULL)
12560         {
12561           if(dealloc) MRIfree(&mri);
12562           free(buf);
12563           errno = 0;
12564           ErrorReturn
12565             (ERROR_BADFILE,
12566              (ERROR_BADFILE,
12567               "bshortWrite(): can't open file %s", fname));
12568         }
12569       fprintf(fp, "%d %d %d %d\n", mri->height, mri->width, mri->nframes, 0);
12570       fclose(fp);
12571 
12572       /* ----- write the data file ----- */
12573       sprintf(fname, "%s_%03d.bshort", stem, i);
12574       if((fp = fopen(fname, "w")) == NULL)
12575         {
12576           if(dealloc) MRIfree(&mri);
12577           free(buf);
12578           errno = 0;
12579           ErrorReturn
12580             (ERROR_BADFILE,
12581              (ERROR_BADFILE, "bshortWrite(): can't open file %s", fname));
12582         }
12583 
12584       for(t = 0;t < mri->nframes;t++)
12585         {
12586           for(j = 0;j < mri->height;j++)
12587             {
12588 
12589 #if (BYTE_ORDER == LITTLE_ENDIAN)
12590               swab(mri->slices[t*mri->depth + i][j], buf,
12591                    mri->width * sizeof(short));
12592 #else
12593               memcpy(buf, mri->slices[t*mri->depth + i][j],
12594                      mri->width * sizeof(short));
12595 #endif
12596 
12597               fwrite(buf, sizeof(short), mri->width, fp);
12598 
12599             }
12600 
12601         }
12602 
12603       fclose(fp);
12604 
12605     }
12606 
12607   free(buf);
12608 
12609   sn = subject_name;
12610   if(mri->subject_name[0] != '\0')
12611     sn = mri->subject_name;
12612 
12613   if(sn != NULL)
12614     {
12615       if((subjects_dir = getenv("SUBJECTS_DIR")) == NULL)
12616         {
12617           errno = 0;
12618           ErrorPrintf
12619             (ERROR_BADPARM,
12620              "bshortWrite(): environment variable SUBJECTS_DIR unset");
12621           if(dealloc) MRIfree(&mri);
12622         }
12623       else
12624         {
12625 
12626           sprintf(subject_dir, "%s/%s", subjects_dir, sn);
12627           if(stat(subject_dir, &stat_buf) < 0)
12628             {
12629               fprintf
12630                 (stderr,
12631                  "can't stat %s; writing to bhdr instead\n", subject_dir);
12632             }
12633           else
12634             {
12635               if(!S_ISDIR(stat_buf.st_mode))
12636                 {
12637                   fprintf
12638                     (stderr,
12639                      "%s is not a directory; writing to bhdr instead\n",
12640                      subject_dir);
12641                 }
12642               else
12643                 {
12644                   sprintf(subject_volume_dir, "%s/mri/T1", subject_dir);
12645                   subject_info = MRIreadInfo(subject_volume_dir);
12646                   if(subject_info == NULL)
12647                     {
12648                       sprintf(subject_volume_dir, "%s/mri/orig", subject_dir);
12649                       subject_info = MRIreadInfo(subject_volume_dir);
12650                       if(subject_info == NULL)
12651                         fprintf(stderr,
12652                                 "can't read the subject's orig or T1 volumes; "
12653                                 "writing to bhdr instead\n");
12654                     }
12655                 }
12656             }
12657 
12658         }
12659 
12660     }
12661 
12662   if(subject_info != NULL)
12663     {
12664       if(subject_info->ras_good_flag == 0)
12665         {
12666           subject_info->x_r = -1.0;
12667           subject_info->x_a = 0.0;
12668           subject_info->x_s =  0.0;
12669           subject_info->y_r =  0.0;
12670           subject_info->y_a = 0.0;
12671           subject_info->y_s = -1.0;
12672           subject_info->z_r =  0.0;
12673           subject_info->z_a = 1.0;
12674           subject_info->z_s =  0.0;
12675           subject_info->c_r =  0.0;
12676           subject_info->c_a = 0.0;
12677           subject_info->c_s =  0.0;
12678         }
12679     }
12680 
12681   cf = bf = ibf = af = iaf = as = bs = cs = ics = r = NULL;
12682   r1 = r2 = r3 = r4 = NULL;
12683 
12684   /* ----- write the register.dat and analyse.dat  or bhdr files ----- */
12685   if(subject_info != NULL)
12686     {
12687 
12688       bad_flag = FALSE;
12689 
12690       if((as = MatrixAlloc(4, 4, MATRIX_REAL)) == NULL)
12691         {
12692           errno = 0;
12693           ErrorPrintf(ERROR_BADPARM, "bshortWrite(): error creating matrix");
12694           bad_flag = TRUE;
12695         }
12696       stuff_four_by_four
12697         (as,
12698          subject_info->x_r,
12699          subject_info->y_r,
12700          subject_info->z_r,
12701          subject_info->c_r,
12702          subject_info->y_r,
12703          subject_info->y_r,
12704          subject_info->y_r,
12705          subject_info->c_r,
12706          subject_info->z_r,
12707          subject_info->z_r,
12708          subject_info->z_r,
12709          subject_info->c_r,
12710          0.0,               0.0,               0.0,               1.0);
12711 
12712       if((af = MatrixAlloc(4, 4, MATRIX_REAL)) == NULL)
12713         {
12714           errno = 0;
12715           ErrorPrintf(ERROR_BADPARM, "bshortWrite(): error creating matrix");
12716           bad_flag = TRUE;
12717         }
12718       stuff_four_by_four(af, mri->x_r, mri->y_r, mri->z_r, mri->c_r,
12719                          mri->y_r, mri->y_r, mri->y_r, mri->c_r,
12720                          mri->z_r, mri->z_r, mri->z_r, mri->c_r,
12721                          0.0,      0.0,      0.0,      1.0);
12722 
12723       if((bs = MatrixAlloc(4, 4, MATRIX_REAL)) == NULL)
12724         {
12725           errno = 0;
12726           ErrorPrintf(ERROR_BADPARM, "bshortWrite(): error creating matrix");
12727           bad_flag = TRUE;
12728         }
12729       stuff_four_by_four(bs, 1, 0, 0, (subject_info->width  - 1) / 2.0,
12730                          0, 1, 0, (subject_info->height - 1) / 2.0,
12731                          0, 0, 1, (subject_info->depth  - 1) / 2.0,
12732                          0, 0, 0,                              1.0);
12733 
12734       if((bf = MatrixAlloc(4, 4, MATRIX_REAL)) == NULL)
12735         {
12736           errno = 0;
12737           ErrorPrintf(ERROR_BADPARM, "bshortWrite(): error creating matrix");
12738           bad_flag = TRUE;
12739         }
12740       stuff_four_by_four(bf, 1, 0, 0, (mri->width  - 1) / 2.0,
12741                          0, 1, 0, (mri->height - 1) / 2.0,
12742                          0, 0, 1, (mri->depth  - 1) / 2.0,
12743                          0, 0, 0,                     1.0);
12744 
12745       if((cs = MatrixAlloc(4, 4, MATRIX_REAL)) == NULL)
12746         {
12747           errno = 0;
12748           ErrorPrintf(ERROR_BADPARM, "bshortWrite(): error creating matrix");
12749           bad_flag = TRUE;
12750         }
12751       stuff_four_by_four
12752         (cs,
12753          -subject_info->xsize, 0, 0,
12754          (subject_info->width  * mri->xsize) / 2.0,
12755          0, 0, subject_info->zsize, -(subject_info->depth  * mri->zsize) / 2.0,
12756          0, -subject_info->ysize, 0,
12757          (subject_info->height * mri->ysize) / 2.0,
12758          0, 0, 0, 1);
12759 
12760       if((cf = MatrixAlloc(4, 4, MATRIX_REAL)) == NULL)
12761         {
12762           errno = 0;
12763           ErrorPrintf(ERROR_BADPARM, "bshortWrite(): error creating matrix");
12764           bad_flag = TRUE;
12765         }
12766       stuff_four_by_four
12767         (cf,
12768          -mri->xsize, 0,          0,  (mri->width  * mri->xsize) / 2.0,
12769          0,           0, mri->zsize, -(mri->depth  * mri->zsize) / 2.0,
12770          0, -mri->ysize,          0,  (mri->height * mri->ysize) / 2.0,
12771          0,           0,          0,                                 1);
12772 
12773       if(bad_flag)
12774         {
12775           errno = 0;
12776           ErrorPrintf
12777             (ERROR_BADPARM,
12778              "bshortWrite(): error creating one "
12779              "or more matrices; aborting register.dat "
12780              "write and writing bhdr instead");
12781           MRIfree(&subject_info);
12782         }
12783 
12784     }
12785 
12786   if(subject_info != NULL)
12787     {
12788 
12789       bad_flag = FALSE;
12790 
12791       if((det = MatrixDeterminant(as)) == 0.0)
12792         {
12793           errno = 0;
12794           ErrorPrintf
12795             (ERROR_BADPARM,
12796              "bshortWrite(): bad determinant in matrix "
12797              "(check structural volume)");
12798           bad_flag = TRUE;
12799         }
12800       if((det = MatrixDeterminant(bs)) == 0.0)
12801         {
12802           errno = 0;
12803           ErrorPrintf
12804             (ERROR_BADPARM,
12805              "bshortWrite(): bad determinant in matrix "
12806              "(check structural volume)");
12807           bad_flag = TRUE;
12808         }
12809       if((det = MatrixDeterminant(cs)) == 0.0)
12810         {
12811           errno = 0;
12812           ErrorPrintf
12813             (ERROR_BADPARM,
12814              "bshortWrite(): bad determinant in matrix "
12815              "(check structural volume)");
12816           bad_flag = TRUE;
12817         }
12818 
12819       if((det = MatrixDeterminant(af)) == 0.0)
12820         {
12821           errno = 0;
12822           ErrorPrintf
12823             (ERROR_BADPARM,
12824              "bshortWrite(): bad determinant in matrix "
12825              "(check functional volume)");
12826           bad_flag = TRUE;
12827         }
12828       if((det = MatrixDeterminant(bf)) == 0.0)
12829         {
12830           errno = 0;
12831           ErrorPrintf
12832             (ERROR_BADPARM,
12833              "bshortWrite(): bad determinant in matrix "
12834              "(check functional volume)");
12835           bad_flag = TRUE;
12836         }
12837       if((det = MatrixDeterminant(cf)) == 0.0)
12838         {
12839           errno = 0;
12840           ErrorPrintf
12841             (ERROR_BADPARM,
12842              "bshortWrite(): bad determinant in matrix "
12843              "(check functional volume)");
12844           bad_flag = TRUE;
12845         }
12846 
12847       if(bad_flag)
12848         {
12849           errno = 0;
12850           ErrorPrintf
12851             (ERROR_BADPARM,
12852              "bshortWrite(): one or more zero "
12853              "determinants; aborting register.dat write and "
12854              "writing bhdr instead");
12855           MRIfree(&subject_info);
12856         }
12857 
12858     }
12859 
12860   if(subject_info != NULL)
12861     {
12862 
12863       bad_flag = FALSE;
12864 
12865       if((iaf = MatrixInverse(af, NULL)) == NULL)
12866         {
12867           errno = 0;
12868           ErrorPrintf(ERROR_BADPARM, "bshortWrite(): error inverting matrix");
12869           bad_flag = TRUE;
12870         }
12871       if((ibf = MatrixInverse(bf, NULL)) == NULL)
12872         {
12873           errno = 0;
12874           ErrorPrintf(ERROR_BADPARM, "bshortWrite(): error inverting matrix");
12875           bad_flag = TRUE;
12876         }
12877       if((ics = MatrixInverse(cs, NULL)) == NULL)
12878         {
12879           errno = 0;
12880           ErrorPrintf(ERROR_BADPARM, "bshortWrite(): error inverting matrix");
12881           bad_flag = TRUE;
12882         }
12883 
12884       if(bad_flag)
12885         {
12886           errno = 0;
12887           ErrorPrintf
12888             (ERROR_BADPARM,
12889              "bshortWrite(): one or more zero "
12890              "determinants; aborting register.dat write and "
12891              "writing bhdr instead");
12892           MRIfree(&subject_info);
12893         }
12894     }
12895 
12896   bad_flag = FALSE;
12897 
12898   if(subject_info != NULL)
12899     {
12900 
12901       if((r1 = MatrixMultiply(bs, ics, NULL)) == NULL)
12902         {
12903           bad_flag = TRUE;
12904           MRIfree(&subject_info);
12905         }
12906 
12907     }
12908 
12909   if(subject_info != NULL)
12910     {
12911 
12912       if((r2 = MatrixMultiply(as, r1, NULL)) == NULL)
12913         {
12914           bad_flag = TRUE;
12915           MRIfree(&subject_info);
12916         }
12917 
12918     }
12919 
12920   if(subject_info != NULL)
12921     {
12922 
12923       if((r3 = MatrixMultiply(iaf, r2, NULL)) == NULL)
12924         {
12925           bad_flag = TRUE;
12926           MRIfree(&subject_info);
12927         }
12928 
12929     }
12930 
12931   if(subject_info != NULL)
12932     {
12933 
12934       if((r4 = MatrixMultiply(ibf, r3, NULL)) == NULL)
12935         {
12936           bad_flag = TRUE;
12937           MRIfree(&subject_info);
12938         }
12939 
12940     }
12941 
12942   if(subject_info != NULL)
12943     {
12944 
12945       if((r = MatrixMultiply(cf, r4, NULL)) == NULL)
12946         {
12947           bad_flag = TRUE;
12948           MRIfree(&subject_info);
12949         }
12950 
12951     }
12952 
12953   if(bad_flag)
12954     {
12955       errno = 0;
12956       ErrorPrintf
12957         (ERROR_BADPARM,
12958          "bshortWrite(): error during matrix "
12959          "multiplications; aborting register.dat write and "
12960          "writing bhdr instead");
12961     }
12962 
12963   if( as != NULL)  MatrixFree( &as);
12964   if( bs != NULL)  MatrixFree( &bs);
12965   if( cs != NULL)  MatrixFree( &cs);
12966   if( af != NULL)  MatrixFree( &af);
12967   if( bf != NULL)  MatrixFree( &bf);
12968   if( cf != NULL)  MatrixFree( &cf);
12969   if(iaf != NULL)  MatrixFree(&iaf);
12970   if(ibf != NULL)  MatrixFree(&ibf);
12971   if(ics != NULL)  MatrixFree(&ics);
12972   if( r1 != NULL)  MatrixFree( &r1);
12973   if( r2 != NULL)  MatrixFree( &r2);
12974   if( r3 != NULL)  MatrixFree( &r3);
12975   if( r4 != NULL)  MatrixFree( &r4);
12976 
12977   if(subject_info != NULL)
12978     {
12979 
12980       if(mri->path_to_t1[0] == '\0')
12981         sprintf(t1_path, ".");
12982       else
12983         strcpy(t1_path, mri->path_to_t1);
12984 
12985       if(FileExists(analyse_fname))
12986         fprintf(stderr, "warning: overwriting file %s\n", analyse_fname);
12987 
12988       if((fp = fopen(analyse_fname, "w")) == NULL)
12989         {
12990           MRIfree(&subject_info);
12991           errno = 0;
12992           ErrorReturn
12993             (ERROR_BADFILE,
12994              (ERROR_BADFILE,
12995               "bshortWrite(): couldn't open file %s for writing",
12996               analyse_fname));
12997         }
12998 
12999       fprintf(fp, "%s\n", t1_path);
13000       fprintf(fp, "%s_%%03d.bshort\n", stem);
13001       fprintf(fp, "%d %d\n", mri->depth, mri->nframes);
13002       fprintf(fp, "%d %d\n", mri->width, mri->height);
13003 
13004       fclose(fp);
13005 
13006       if(FileExists(analyse_fname))
13007         fprintf(stderr, "warning: overwriting file %s\n", register_fname);
13008 
13009       if((fp = fopen(register_fname, "w")) == NULL)
13010         {
13011           MRIfree(&subject_info);
13012           errno = 0;
13013           ErrorReturn
13014             (ERROR_BADFILE,
13015              (ERROR_BADFILE,
13016               "bshortWrite(): couldn't open file %s for writing",
13017               register_fname));
13018         }
13019 
13020       fprintf(fp, "%s\n", sn);
13021       fprintf(fp, "%g\n", mri->xsize);
13022       fprintf(fp, "%g\n", mri->zsize);
13023       fprintf(fp, "%g\n", 1.0);
13024       fprintf(fp, "%g %g %g %g\n",
13025               *MATRIX_RELT(r, 1, 1),
13026               *MATRIX_RELT(r, 1, 2),
13027               *MATRIX_RELT(r, 1, 3),
13028               *MATRIX_RELT(r, 1, 4));
13029       fprintf(fp, "%g %g %g %g\n",
13030               *MATRIX_RELT(r, 2, 1),
13031               *MATRIX_RELT(r, 2, 2),
13032               *MATRIX_RELT(r, 2, 3),
13033               *MATRIX_RELT(r, 2, 4));
13034       fprintf(fp, "%g %g %g %g\n",
13035               *MATRIX_RELT(r, 3, 1),
13036               *MATRIX_RELT(r, 3, 2),
13037               *MATRIX_RELT(r, 3, 3),
13038               *MATRIX_RELT(r, 3, 4));
13039       fprintf(fp, "%g %g %g %g\n",
13040               *MATRIX_RELT(r, 4, 1),
13041               *MATRIX_RELT(r, 4, 2),
13042               *MATRIX_RELT(r, 4, 3),
13043               *MATRIX_RELT(r, 4, 4));
13044 
13045       fclose(fp);
13046 
13047       MatrixFree(&r);
13048 
13049     }
13050 
13051   if(subject_info == NULL)
13052     {
13053       sprintf(fname, "%s.bhdr", stem);
13054       if((fp = fopen(fname, "w")) == NULL)
13055         {
13056           if(dealloc) MRIfree(&mri);
13057           errno = 0;
13058           ErrorReturn
13059             (ERROR_BADFILE,
13060              (ERROR_BADFILE, "bshortWrite(): can't open file %s", fname));
13061         }
13062 
13063       result = write_bhdr(mri, fp);
13064 
13065       fclose(fp);
13066 
13067       if(result != NO_ERROR)
13068         return(result);
13069 
13070     }
13071   else
13072     MRIfree(&subject_info);
13073 
13074   if(dealloc) MRIfree(&mri);
13075 
13076   return(NO_ERROR);
13077 
13078 } /* end bshortWrite() */
13079 
13080 /*-------------------------------------------------------------------
13081   bshortRead() - obsolete. Use bvolumeRead.
13082   -------------------------------------------------------------------*/
13083 static MRI *bshortRead(char *fname_passed, int read_volume)
13084 {
13085 
13086   MRI *mri;
13087   FILE *fp;
13088   char fname[STRLEN];
13089   char directory[STRLEN];
13090   char stem[STRLEN];
13091   int swap_bytes_flag;
13092   int slice, frame, row, k;
13093   int nread;
13094 
13095   mri = get_b_info(fname_passed, read_volume, directory, stem, MRI_SHORT);
13096   if(mri == NULL)
13097     return(NULL);
13098 
13099   if(read_volume)
13100     {
13101 
13102       sprintf(fname, "%s/%s_%03d.hdr", directory, stem, 0);
13103       if((fp = fopen(fname, "r")) == NULL){
13104         fprintf
13105           (stderr, "can't open file %s; assuming big-endian bvolume\n", fname);
13106         swap_bytes_flag = 0;
13107       }
13108       else
13109         {
13110           fscanf(fp, "%*d %*d %*d %d", &swap_bytes_flag);
13111 #if (BYTE_ORDER == LITTLE_ENDIAN)
13112           swap_bytes_flag = !swap_bytes_flag;
13113 #endif
13114           fclose(fp);
13115         }
13116 
13117       for(slice = 0;slice < mri->depth; slice++){
13118 
13119         sprintf(fname, "%s/%s_%03d.bshort", directory, stem, slice);
13120         if((fp = fopen(fname, "r")) == NULL){
13121           MRIfree(&mri);
13122           errno = 0;
13123           ErrorReturn(NULL, (ERROR_BADFILE,
13124                              "bshortRead(): error opening file %s", fname));
13125         }
13126 
13127         for(frame = 0; frame < mri->nframes; frame ++){
13128           k = slice + mri->depth*frame;
13129           for(row = 0;row < mri->height; row++){
13130 
13131             /* read in a column */
13132             nread = fread(mri->slices[k][row], sizeof(short), mri->width, fp);
13133             if( nread != mri->width){
13134               fclose(fp);
13135               MRIfree(&mri);
13136               errno = 0;
13137               ErrorReturn
13138                 (NULL,
13139                  (ERROR_BADFILE,
13140                   "bshortRead(): error reading from file %s", fname));
13141             }
13142 
13143             if(swap_bytes_flag)
13144               swab(mri->slices[k][row], mri->slices[k][row],
13145                    mri->width * sizeof(short));
13146 
13147           } /* row loop */
13148         } /* frame loop */
13149         fclose(fp);
13150       }
13151     }
13152 
13153   return(mri);
13154 
13155 } /* end bshortRead() */
13156 
13157 
13158 /*-------------------------------------------------------------------
13159   bfloatRead() - obsolete. Use bvolumeRead.
13160   -------------------------------------------------------------------*/
13161 static MRI *bfloatRead(char *fname_passed, int read_volume)
13162 {
13163 
13164   MRI *mri;
13165   FILE *fp;
13166   char fname[STRLEN];
13167   char directory[STRLEN];
13168   char stem[STRLEN];
13169   int swap_bytes_flag;
13170   int i, j, k;
13171 
13172   mri = get_b_info(fname_passed, read_volume, directory, stem, MRI_FLOAT);
13173   if(mri == NULL)
13174     return(NULL);
13175 
13176   if(read_volume)
13177     {
13178 
13179       sprintf(fname, "%s/%s_%03d.hdr", directory, stem, 0);
13180       if((fp = fopen(fname, "r")) == NULL)
13181         {
13182           fprintf
13183             (stderr,
13184              "INFO: Can't open file %s; assuming big-endian bshorts\n",
13185              fname);
13186           swap_bytes_flag = 0;
13187         }
13188       else
13189         {
13190           fscanf(fp, "%*d %*d %*d %d", &swap_bytes_flag);
13191 #if (BYTE_ORDER == LITTLE_ENDIAN)
13192           swap_bytes_flag = !swap_bytes_flag;
13193 #endif
13194           fclose(fp);
13195         }
13196 
13197       printf("swap = %d\n",swap_bytes_flag);
13198 
13199       for(i = 0;i < mri->depth;i++)
13200         {
13201 
13202           sprintf(fname, "%s/%s_%03d.bfloat", directory, stem, i);
13203 
13204           if((fp = fopen(fname, "r")) == NULL)
13205             {
13206               MRIfree(&mri);
13207               errno = 0;
13208               ErrorReturn
13209                 (NULL,
13210                  (ERROR_BADFILE,
13211                   "bfloatRead(): error opening file %s", fname));
13212             }
13213 
13214           for(j = 0;j < mri->height;j++)
13215             {
13216               if(fread(mri->slices[i][j], sizeof(float), mri->width, fp) !=
13217                  mri->width)
13218                 {
13219                   fclose(fp);
13220                   MRIfree(&mri);
13221                   errno = 0;
13222                   ErrorReturn
13223                     (NULL,
13224                      (ERROR_BADFILE,
13225                       "bfloatRead(): error reading from file %s", fname));
13226                 }
13227               if(swap_bytes_flag)
13228                 {
13229                   for(k = 0;k < mri->depth;k++)
13230                     mri->slices[i][j][k] = swapFloat(mri->slices[i][j][k]);
13231                 }
13232             }
13233 
13234           fclose(fp);
13235 
13236         }
13237 
13238     }
13239 
13240   return(mri);
13241 
13242 } /* end bfloatRead() */
13243 
13244 
13245 /*-------------------------------------------------------------------------*/
13246 static MRI *analyzeReadOld(char *fname, int read_volume)
13247 {
13248 
13249   MRI *mri = NULL;
13250   FILE *fp;
13251   char hdr_fname[STRLEN];
13252   char mat_fname[STRLEN];
13253   char *c;
13254   dsr hdr;
13255   int dtype;
13256   int flip_flag = 0;
13257   int i, j, k;
13258   float dx, dy, dz;
13259   int nread;
13260   unsigned char *buf;
13261   int bytes_per_voxel;
13262   int bufsize;
13263   MATRIX *m;
13264   MATRIX *center_index_mat;
13265   MATRIX *center_ras_mat;
13266   float xfov, yfov, zfov;
13267 
13268   c = strrchr(fname, '.');
13269   if(c == NULL)
13270     {
13271       errno = 0;
13272       ErrorReturn
13273         (NULL, (ERROR_BADPARM, "analyzeRead(): bad file name %s", fname));
13274     }
13275   if(strcmp(c, ".img") != 0)
13276     {
13277       errno = 0;
13278       ErrorReturn
13279         (NULL, (ERROR_BADPARM, "analyzeRead(): bad file name %s", fname));
13280     }
13281 
13282   strcpy(hdr_fname, fname);
13283   sprintf(hdr_fname + (c - fname), ".hdr");
13284 
13285   strcpy(mat_fname, fname);
13286   sprintf(mat_fname + (c - fname), ".mat");
13287 
13288   /* Open the header file */
13289   if((fp = fopen(hdr_fname, "r")) == NULL)
13290     {
13291       errno = 0;
13292       ErrorReturn(NULL, (ERROR_BADFILE, "read_analyze_header(): "
13293                          "error opening file %s", fname));
13294     }
13295 
13296   /* Read the header file */
13297   fread(&hdr, sizeof(hdr), 1, fp);
13298   fclose(fp);
13299 
13300   if(hdr.hk.sizeof_hdr != sizeof(hdr))
13301     {
13302       flip_flag = 1;
13303       swap_analyze_header(&hdr);
13304     }
13305 
13306   if(hdr.dime.datatype == DT_UNSIGNED_CHAR)
13307     {
13308       dtype = MRI_UCHAR;
13309       bytes_per_voxel = 1;
13310     }
13311   else if(hdr.dime.datatype == DT_SIGNED_SHORT)
13312     {
13313       dtype = MRI_SHORT;
13314       bytes_per_voxel = 2;
13315     }
13316   else if(hdr.dime.datatype == DT_SIGNED_INT)
13317     {
13318       dtype = MRI_INT;
13319       bytes_per_voxel = 4;
13320     }
13321   else if(hdr.dime.datatype == DT_FLOAT)
13322     {
13323       dtype = MRI_FLOAT;
13324       bytes_per_voxel = 4;
13325     }
13326   else if(hdr.dime.datatype == DT_DOUBLE)
13327     {
13328       dtype = MRI_FLOAT;
13329       bytes_per_voxel = 8;
13330     }
13331   else
13332     {
13333       errno = 0;
13334       ErrorReturn(NULL, (ERROR_UNSUPPORTED, "analyzeRead: "
13335                          "unsupported data type %d", hdr.dime.datatype));
13336     }
13337 
13338   /* ----- allocate the mri structure ----- */
13339   if(read_volume)
13340     mri = MRIalloc(hdr.dime.dim[1], hdr.dime.dim[2], hdr.dime.dim[3], dtype);
13341   else
13342     mri = MRIalloc(hdr.dime.dim[1], hdr.dime.dim[2], hdr.dime.dim[3], dtype);
13343 
13344   mri->xsize = hdr.dime.pixdim[1];
13345   mri->ysize = hdr.dime.pixdim[2];
13346   mri->zsize = hdr.dime.pixdim[3];
13347 
13348   mri->thick = mri->zsize;
13349   mri->ps = mri->xsize;
13350   mri->xend = mri->width * mri->xsize / 2.0;   mri->xstart = -mri->xend;
13351   mri->yend = mri->height * mri->ysize / 2.0;  mri->ystart = -mri->yend;
13352   mri->zend = mri->depth * mri->zsize / 2.0;   mri->zstart = -mri->zend;
13353   xfov = mri->xend - mri->xstart;
13354   yfov = mri->yend - mri->ystart;
13355   zfov = mri->zend - mri->zstart;
13356 
13357   mri->fov =
13358     (xfov > yfov ? (xfov > zfov ? xfov : zfov) : (yfov > zfov ? yfov : zfov));
13359 
13360   /* --- default (no .mat file) --- */
13361   mri->x_r =  1.0;  mri->x_a = 0.0;  mri->x_s = 0.0;
13362   mri->y_r =  0.0;  mri->y_a = 1.0;  mri->y_s = 0.0;
13363   mri->z_r =  0.0;  mri->z_a = 0.0;  mri->z_s = 1.0;
13364 
13365   /* --- originator gives the voxel index of (r, a, s) = (0, 0, 0) --- */
13366   dx = (mri->width  - 1.0) / 2. - (float)(((short *)hdr.hist.originator)[0]);
13367   dy = (mri->height - 1.0) / 2. - (float)(((short *)hdr.hist.originator)[1]);
13368   dz = (mri->depth  - 1.0) / 2. - (float)(((short *)hdr.hist.originator)[2]);
13369 
13370   mri->c_r = (dx * mri->x_r) + (dy * mri->y_r) + (dz * mri->z_r);
13371   mri->c_a = (dx * mri->x_a) + (dy * mri->y_a) + (dz * mri->z_a);
13372   mri->c_s = (dx * mri->x_s) + (dy * mri->y_s) + (dz * mri->z_s);
13373 
13374   mri->ras_good_flag = 1;
13375 
13376   strcpy(mri->fname, fname);
13377 
13378   if(read_volume)
13379     {
13380 
13381       if((fp = fopen(fname, "r")) == NULL)
13382         {
13383           MRIfree(&mri);
13384           errno = 0;
13385           ErrorReturn
13386             (NULL,
13387              (ERROR_BADFILE, "analyzeRead: error opening file %s", fname));
13388         }
13389 
13390       fseek(fp, (int)(hdr.dime.vox_offset), SEEK_SET);
13391 
13392       bufsize = mri->width * bytes_per_voxel;
13393       buf = (unsigned char *)malloc(bufsize);
13394 
13395       for(k = 0;k < mri->depth;k++)
13396         {
13397           for(j = 0;j < mri->height;j++)
13398             {
13399 
13400               nread = fread(buf, bytes_per_voxel, mri->width, fp);
13401               if(nread != mri->width)
13402                 {
13403                   free(buf);
13404                   fclose(fp);
13405                   errno = 0;
13406                   ErrorReturn
13407                     (NULL,
13408                      (ERROR_BADFILE,
13409                       "analyzeRead: error reading from file %s\n", fname));
13410                 }
13411 
13412               if(flip_flag)
13413                 nflip(buf, bytes_per_voxel, mri->width);
13414 
13415 
13416               for(i = 0;i < mri->width;i++)
13417                 {
13418                   if(hdr.dime.datatype == DT_UNSIGNED_CHAR)
13419                     MRIvox(mri, i, j, k) = buf[i];
13420                   if(hdr.dime.datatype == DT_SIGNED_SHORT)
13421                     MRISvox(mri, i, j, k) = ((short *)buf)[i];
13422                   if(hdr.dime.datatype == DT_SIGNED_INT)
13423                     MRIIvox(mri, i, j, k) = ((int *)buf)[i];
13424                   if(hdr.dime.datatype == DT_FLOAT)
13425                     MRIFvox(mri, i, j, k) = ((float *)buf)[i];
13426                   if(hdr.dime.datatype == DT_DOUBLE)
13427                     MRIFvox(mri, i, j, k) = (float)(((double *)buf)[i]);
13428                 }
13429 
13430             }
13431         }
13432 
13433       free(buf);
13434       fclose(fp);
13435 
13436     }
13437 
13438   /* ----- read mat file ----- */
13439   if(FileExists(mat_fname))
13440     {
13441 
13442       m = MatlabRead(mat_fname);
13443 
13444       if(m == NULL)
13445         {
13446           MRIfree(&mri);
13447           return(NULL);
13448         }
13449 
13450       if(m->rows != 4 || m->cols != 4)
13451         {
13452           MRIfree(&mri);
13453           errno = 0;
13454           ErrorReturn
13455             (NULL,
13456              (ERROR_BADFILE,
13457               "analyzeRead(): not a 4 by 4 matrix in file %s", mat_fname));
13458         }
13459 
13460       /* swap y and z here ?*/
13461       mri->x_r = *MATRIX_RELT(m, 1, 1);
13462       mri->y_r = *MATRIX_RELT(m, 1, 2);
13463       mri->z_r = *MATRIX_RELT(m, 1, 3);
13464       mri->x_a = *MATRIX_RELT(m, 2, 1);
13465       mri->y_a = *MATRIX_RELT(m, 2, 2);
13466       mri->z_a = *MATRIX_RELT(m, 2, 3);
13467       mri->x_s = *MATRIX_RELT(m, 3, 1);
13468       mri->y_s = *MATRIX_RELT(m, 3, 2);
13469       mri->z_s = *MATRIX_RELT(m, 3, 3);
13470 
13471       mri->xsize =
13472         sqrt(mri->x_r * mri->x_r + mri->x_a * mri->x_a + mri->x_s * mri->x_s);
13473       mri->ysize =
13474         sqrt(mri->y_r * mri->y_r + mri->y_a * mri->y_a + mri->y_s * mri->y_s);
13475       mri->zsize =
13476         sqrt(mri->z_r * mri->z_r + mri->z_a * mri->z_a + mri->z_s * mri->z_s);
13477 
13478       mri->x_r = mri->x_r / mri->xsize;
13479       mri->x_a = mri->x_a / mri->xsize;
13480       mri->x_s = mri->x_s / mri->xsize;
13481       mri->y_r = mri->y_r / mri->ysize;
13482       mri->y_a = mri->y_a / mri->ysize;
13483       mri->y_s = mri->y_s / mri->ysize;
13484       mri->z_r = mri->z_r / mri->zsize;
13485       mri->z_a = mri->z_a / mri->zsize;
13486       mri->z_s = mri->z_s / mri->zsize;
13487 
13488       center_index_mat = MatrixAlloc(4, 1, MATRIX_REAL);
13489 
13490       /* Is this right?? */
13491       /* --- matlab matrices start at 1, so the middle index is
13492          [(width, height, depth)+(1, 1, 1)]/2, (not -) --- */
13493       *MATRIX_RELT(center_index_mat, 1, 1) = (mri->width + 1.0) / 2.0;
13494       *MATRIX_RELT(center_index_mat, 2, 1) = (mri->height + 1.0) / 2.0;
13495       *MATRIX_RELT(center_index_mat, 3, 1) = (mri->depth + 1.0) / 2.0;
13496       *MATRIX_RELT(center_index_mat, 4, 1) = 1.0;
13497 
13498       center_ras_mat = MatrixMultiply(m, center_index_mat, NULL);
13499       if(center_ras_mat == NULL)
13500         {
13501 
13502           errno = 0;
13503           ErrorPrintf(ERROR_BADPARM, "multiplying: m * cim:\n");
13504           ErrorPrintf(ERROR_BADPARM, "m = \n");
13505           MatrixPrint(stderr, m);
13506           ErrorPrintf(ERROR_BADPARM, "cim = \n");
13507           MatrixPrint(stderr, center_index_mat);
13508 
13509           MatrixFree(&m);
13510           MatrixFree(&center_index_mat);
13511           MatrixFree(&center_ras_mat);
13512           MRIfree(&mri);
13513           errno = 0;
13514           ErrorReturn
13515             (NULL,
13516              (ERROR_BADPARM, "analyzeRead(): error in matrix multiplication"));
13517         }
13518 
13519       mri->c_r = *MATRIX_RELT(center_ras_mat, 1, 1);
13520       mri->c_a = *MATRIX_RELT(center_ras_mat, 2, 1);
13521       mri->c_s = *MATRIX_RELT(center_ras_mat, 3, 1);
13522 
13523       MatrixFree(&m);
13524       MatrixFree(&center_index_mat);
13525       MatrixFree(&center_ras_mat);
13526 
13527     }
13528 
13529   return(mri);
13530 
13531 } /* end analyzeRead() */
13532 
13533 static void nflip(unsigned char *buf, int b, int n)
13534 {
13535   int i, j;
13536   unsigned char *copy;
13537 
13538   copy = (unsigned char *)malloc(b);
13539   for(i = 0;i < n;i++)
13540     {
13541       memcpy(copy, &buf[i*b], b);
13542       for(j = 0;j < b;j++)
13543         buf[i*b+j] = copy[b-j-1];
13544     }
13545   free(copy);
13546 
13547 } /* end nflip() */
13548 
13549 #endif
13550 #include "gca.h"
13551 static MRI *
13552 readGCA(char *fname)
13553 {
13554   GCA *gca ;
13555   MRI *mri ;
13556 
13557   gca = GCAread(fname) ;
13558   if (!gca)
13559     return(NULL) ;
13560   mri = GCAbuildMostLikelyVolume(gca, NULL) ;
13561   GCAfree(&gca) ;
13562   return(mri) ;
13563 }
13564 
13565 MRI *
13566 MRIremoveNaNs(MRI *mri_src, MRI *mri_dst)
13567 {
13568   int x, y, z, nans=0 ;
13569   float val ;
13570 
13571   if (mri_dst != mri_src)
13572     mri_dst = MRIcopy(mri_src, mri_dst) ;
13573 
13574   for (x = 0 ; x < mri_dst->width ; x++)
13575     {
13576       for (y = 0 ; y < mri_dst->height ; y++)
13577         {
13578           for (z = 0 ; z < mri_dst->depth ; z++)
13579             {
13580               val = MRIgetVoxVal(mri_dst, x, y, z, 0) ;
13581               if (!finite(val))
13582                 {
13583                   nans++ ;
13584                   MRIsetVoxVal(mri_dst, x, y, z, 0, 0) ;
13585                 }
13586             }
13587         }
13588     }
13589   if (nans > 0)
13590     ErrorPrintf
13591       (ERROR_BADPARM,
13592        "WARNING: %d NaNs found in volume %s...\n", nans, mri_src->fname) ;
13593   return(mri_dst) ;
13594 }
13595 
13596 int
13597 MRIaddCommandLine(MRI *mri, char *cmdline)
13598 {
13599   int i ;
13600   if (mri->ncmds >= MAX_CMDS)
13601     ErrorExit
13602       (ERROR_NOMEMORY,
13603        "MRIaddCommandLine: can't add cmd %s (%d)", cmdline, mri->ncmds) ;
13604 
13605   i = mri->ncmds++ ;
13606   mri->cmdlines[i] = (char *)calloc(strlen(cmdline)+1, sizeof(char)) ;
13607   strcpy(mri->cmdlines[i], cmdline) ;
13608   return(NO_ERROR) ;
13609 }
13610 
13611 
13612 //---------------------------------------------------------------
13613 #if 0 // old versions without support for compressed nifti
13614 /*------------------------------------------------------------------
13615   niiRead() - note: there is also an nifti1Read(). Make sure to
13616   edit both.
13617   -----------------------------------------------------------------*/
13618 static MRI *niiRead(char *fname, int read_volume)
13619 {
13620 
13621   FILE *fp;
13622   MRI *mri;
13623   struct nifti_1_header hdr;
13624   int nslices;
13625   int fs_type;
13626   float time_units_factor, space_units_factor;
13627   int swapped_flag;
13628   int n_read, i, j, k, t;
13629   int bytes_per_voxel,time_units,space_units ;
13630 
13631   fp = fopen(fname, "r");
13632   if(fp == NULL){
13633     errno = 0;
13634     ErrorReturn
13635       (NULL, (ERROR_BADFILE, "niiRead(): error opening file %s", fname));
13636   }
13637 
13638   if(fread(&hdr, sizeof(hdr), 1, fp) != 1){
13639     fclose(fp);
13640     errno = 0;
13641     ErrorReturn
13642       (NULL,
13643        (ERROR_BADFILE, "niiRead(): error reading header from %s", fname));
13644   }
13645 
13646   fclose(fp);
13647 
13648   swapped_flag = FALSE;
13649   if(hdr.dim[0] < 1 || hdr.dim[0] > 7){
13650     swapped_flag = TRUE;
13651     swap_nifti_1_header(&hdr);
13652     if(hdr.dim[0] < 1 || hdr.dim[0] > 7)
13653       {
13654         ErrorReturn(NULL, (ERROR_BADFILE,
13655                            "niiRead(): bad number of dimensions (%hd) in %s",
13656                            hdr.dim[0], fname));
13657       }
13658   }
13659 
13660   if(memcmp(hdr.magic, NII_MAGIC, 4) != 0){
13661     ErrorReturn
13662       (NULL, (ERROR_BADFILE, "niiRead(): bad magic number in %s", fname));
13663   }
13664 
13665   if(hdr.dim[0] != 3 && hdr.dim[0] != 4){
13666     ErrorReturn(NULL,
13667                 (ERROR_UNSUPPORTED,
13668                  "niiRead(): %hd dimensions in %s; unsupported",
13669                  hdr.dim[0], fname));
13670   }
13671 
13672   if(hdr.datatype == DT_NONE || hdr.datatype == DT_UNKNOWN)
13673     {
13674       ErrorReturn(NULL,
13675                   (ERROR_UNSUPPORTED,
13676                    "niiRead(): unknown or no data type in %s; bailing out",
13677                    fname));
13678     }
13679 
13680   space_units  = XYZT_TO_SPACE(hdr.xyzt_units) ;
13681   if(space_units == NIFTI_UNITS_METER)       space_units_factor = 1000.0;
13682   else if(space_units == NIFTI_UNITS_MM)     space_units_factor = 1.0;
13683   else if(space_units == NIFTI_UNITS_MICRON) space_units_factor = 0.001;
13684   else
13685     ErrorReturn
13686       (NULL,
13687        (ERROR_BADFILE,
13688         "niiRead(): unknown space units %d in %s", space_units,
13689                        fname));
13690 
13691   time_units = XYZT_TO_TIME (hdr.xyzt_units) ;
13692   if(time_units == NIFTI_UNITS_SEC)       time_units_factor = 1000.0;
13693   else if(time_units == NIFTI_UNITS_MSEC) time_units_factor = 1.0;
13694   else if(time_units == NIFTI_UNITS_USEC) time_units_factor = 0.001;
13695   else{
13696     if(hdr.dim[4] > 1){
13697       ErrorReturn
13698         (NULL, (ERROR_BADFILE, "niiRead(): unknown time units %d in %s",
13699                 time_units,fname));
13700     }
13701     else time_units_factor = 0;
13702   }
13703   //printf("hdr.xyzt_units = %d, time_units = %d, %g, %g\n",
13704   // hdr.xyzt_units,time_units,hdr.pixdim[4],time_units_factor);
13705 
13706   /*
13707     nifti1.h says: slice_code = If this is nonzero,
13708     AND if slice_dim is nonzero, AND
13709     if slice_duration is positive, indicates the timing
13710     pattern of the slice acquisition.
13711     not yet supported here
13712   */
13713 
13714   if(hdr.slice_code != 0 && DIM_INFO_TO_SLICE_DIM(hdr.dim_info) != 0
13715      && hdr.slice_duration > 0.0){
13716     ErrorReturn(NULL,
13717                 (ERROR_UNSUPPORTED,
13718                  "niiRead(): unsupported timing pattern in %s", fname));
13719   }
13720 
13721   if(hdr.dim[0] == 3)
13722     nslices = 1;
13723   else
13724     nslices = hdr.dim[4];
13725 
13726   if(hdr.scl_slope == 0){
13727     // voxel values are unscaled -- we use the file's data type
13728     if(hdr.datatype == DT_UNSIGNED_CHAR){
13729       fs_type = MRI_UCHAR;
13730       bytes_per_voxel = 1;
13731     }
13732     else if(hdr.datatype == DT_SIGNED_SHORT){
13733       fs_type = MRI_SHORT;
13734       bytes_per_voxel = 2;
13735     }
13736     else if(hdr.datatype == DT_SIGNED_INT){
13737       fs_type = MRI_INT;
13738       bytes_per_voxel = 4;
13739     }
13740     else if(hdr.datatype == DT_FLOAT){
13741       fs_type = MRI_FLOAT;
13742       bytes_per_voxel = 4;
13743     }
13744     else{
13745       ErrorReturn
13746         (NULL,
13747          (ERROR_UNSUPPORTED,
13748           "niiRead(): unsupported datatype %d (with scl_slope = 0) in %s",
13749           hdr.datatype, fname));
13750     }
13751   }
13752   else{
13753     // we must scale the voxel values
13754     if(   hdr.datatype != DT_UNSIGNED_CHAR
13755           && hdr.datatype != DT_SIGNED_SHORT
13756           && hdr.datatype != DT_SIGNED_INT
13757           && hdr.datatype != DT_FLOAT
13758           && hdr.datatype != DT_DOUBLE
13759           && hdr.datatype != DT_INT8
13760           && hdr.datatype != DT_UINT16
13761           && hdr.datatype != DT_UINT32){
13762       ErrorReturn
13763         (NULL,
13764          (ERROR_UNSUPPORTED,
13765           "niiRead(): unsupported datatype %d (with scl_slope != 0) in %s",
13766           hdr.datatype, fname));
13767     }
13768     fs_type = MRI_FLOAT;
13769     bytes_per_voxel = 0; /* set below -- avoid the compiler warning */
13770   }
13771 
13772   if(read_volume)
13773     mri = MRIallocSequence(hdr.dim[1],hdr.dim[2],hdr.dim[3],fs_type,nslices);
13774   else{
13775     mri = MRIallocHeader(hdr.dim[1], hdr.dim[2], hdr.dim[3], fs_type);
13776     mri->nframes = nslices;
13777   }
13778 
13779   if(mri == NULL) return(NULL);
13780 
13781   mri->xsize = hdr.pixdim[1];
13782   mri->ysize = hdr.pixdim[2];
13783   mri->zsize = hdr.pixdim[3];
13784   if(hdr.dim[0] == 4) mri->tr = hdr.pixdim[4];
13785 
13786   if(hdr.qform_code == 0){
13787     printf("WARNING: missing NIfTI-1 orientation (qform_code = 0)\n");
13788     printf("WARNING: your volume will probably be incorrectly oriented\n");
13789     mri->x_r = 1.0;  mri->x_a = 0.0;  mri->x_s = 0.0;
13790     mri->y_r = 0.0;  mri->y_a = 1.0;  mri->y_s = 0.0;
13791     mri->z_r = 0.0;  mri->z_a = 0.0;  mri->z_s = 1.0;
13792     mri->c_r = mri->xsize * mri->width / 2.0;
13793     mri->c_a = mri->ysize * mri->height / 2.0;
13794     mri->c_s = mri->zsize * mri->depth / 2.0;
13795   }
13796   else if(hdr.sform_code <= 0){
13797     if(niftiQformToMri(mri, &hdr) != NO_ERROR){
13798       MRIfree(&mri);
13799       return(NULL);
13800     }
13801   }
13802   else{
13803     if(niftiSformToMri(mri, &hdr) != NO_ERROR){
13804       MRIfree(&mri);
13805       return(NULL);
13806     }
13807   }
13808 
13809   mri->xsize = mri->xsize * space_units_factor;
13810   mri->ysize = mri->ysize * space_units_factor;
13811   mri->zsize = mri->zsize * space_units_factor;
13812   mri->c_r = mri->c_r * space_units_factor;
13813   mri->c_a = mri->c_a * space_units_factor;
13814   mri->c_s = mri->c_s * space_units_factor;
13815   if(hdr.dim[0] == 4)  mri->tr = mri->tr * time_units_factor;
13816 
13817   if(!read_volume) return(mri);
13818 
13819   fp = fopen(fname, "r");
13820   if(fp == NULL) {
13821     MRIfree(&mri);
13822     errno = 0;
13823     ErrorReturn(NULL, (ERROR_BADFILE,
13824                        "niiRead(): error opening file %s", fname));
13825   }
13826 
13827   if(fseek(fp, (long)(hdr.vox_offset), SEEK_SET) == -1){
13828     fclose(fp);
13829     MRIfree(&mri);
13830     errno = 0;
13831     ErrorReturn(NULL, (ERROR_BADFILE,
13832                        "niiRead(): error finding voxel data in %s", fname));
13833   }
13834 
13835   if(hdr.scl_slope == 0){
13836     // no voxel value scaling needed
13837     void *buf;
13838 
13839     for(t = 0;t < mri->nframes;t++)
13840       for(k = 0;k < mri->depth;k++)
13841         for(j = 0;j < mri->height;j++) {
13842           buf = &MRIseq_vox(mri, 0, j, k, t);
13843 
13844           n_read = fread(buf, bytes_per_voxel, mri->width, fp);
13845           if(n_read != mri->width) {
13846             fclose(fp);
13847             MRIfree(&mri);
13848             errno = 0;
13849             ErrorReturn(NULL, (ERROR_BADFILE,
13850                                "niiRead(): error reading from %s", fname));
13851           }
13852 
13853           if(swapped_flag) {
13854             if(bytes_per_voxel == 2)
13855               byteswapbufshort(buf, bytes_per_voxel * mri->width);
13856             if(bytes_per_voxel == 4)
13857               byteswapbuffloat(buf, bytes_per_voxel * mri->width);
13858           }
13859 
13860         }
13861 
13862   }
13863   else{
13864     // voxel value scaling needed
13865     if(hdr.datatype == DT_UNSIGNED_CHAR) {
13866       unsigned char *buf;
13867       bytes_per_voxel = 1;
13868       buf = (unsigned char *)malloc(mri->width * bytes_per_voxel);
13869       for(t = 0;t < mri->nframes;t++)
13870         for(k = 0;k < mri->depth;k++)
13871           for(j = 0;j < mri->height;j++) {
13872             n_read = fread(buf, bytes_per_voxel, mri->width, fp);
13873             if(n_read != mri->width) {
13874               free(buf);
13875               fclose(fp);
13876               MRIfree(&mri);
13877               errno = 0;
13878               ErrorReturn(NULL,
13879                           (ERROR_BADFILE,
13880                            "niiRead(): error reading from %s", fname));
13881             }
13882             for(i = 0;i < mri->width;i++)
13883               MRIFseq_vox(mri, i, j, k, t) =
13884                 hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
13885           }
13886       free(buf);
13887     }
13888 
13889     if(hdr.datatype == DT_SIGNED_SHORT){
13890       short *buf;
13891       bytes_per_voxel = 2;
13892       buf = (short *)malloc(mri->width * bytes_per_voxel);
13893       for(t = 0;t < mri->nframes;t++)
13894         for(k = 0;k < mri->depth;k++)
13895           for(j = 0;j < mri->height;j++) {
13896             n_read = fread(buf, bytes_per_voxel, mri->width, fp);
13897             if(n_read != mri->width) {
13898               free(buf);
13899               fclose(fp);
13900               MRIfree(&mri);
13901               errno = 0;
13902               ErrorReturn(NULL,
13903                           (ERROR_BADFILE,
13904                            "niiRead(): error reading from %s", fname));
13905             }
13906             if(swapped_flag)
13907               byteswapbufshort(buf, bytes_per_voxel * mri->width);
13908             for(i = 0;i < mri->width;i++)
13909               MRIFseq_vox(mri, i, j, k, t) =
13910                 hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
13911           }
13912       free(buf);
13913     }
13914 
13915     if(hdr.datatype == DT_SIGNED_INT) {
13916       int *buf;
13917       bytes_per_voxel = 4;
13918       buf = (int *)malloc(mri->width * bytes_per_voxel);
13919       for(t = 0;t < mri->nframes;t++)
13920         for(k = 0;k < mri->depth;k++)
13921           for(j = 0;j < mri->height;j++) {
13922             n_read = fread(buf, bytes_per_voxel, mri->width, fp);
13923             if(n_read != mri->width){
13924               free(buf);
13925               fclose(fp);
13926               MRIfree(&mri);
13927               errno = 0;
13928               ErrorReturn(NULL,
13929                           (ERROR_BADFILE,
13930                            "niiRead(): error reading from %s", fname));
13931             }
13932             if(swapped_flag)
13933               byteswapbuffloat(buf, bytes_per_voxel * mri->width);
13934             for(i = 0;i < mri->width;i++)
13935               MRIFseq_vox(mri, i, j, k, t) =
13936                 hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
13937           }
13938       free(buf);
13939     }
13940 
13941     if(hdr.datatype == DT_FLOAT) {
13942       float *buf;
13943       bytes_per_voxel = 4;
13944       buf = (float *)malloc(mri->width * bytes_per_voxel);
13945       for(t = 0;t < mri->nframes;t++)
13946         for(k = 0;k < mri->depth;k++)
13947           for(j = 0;j < mri->height;j++) {
13948             n_read = fread(buf, bytes_per_voxel, mri->width, fp);
13949             if(n_read != mri->width) {
13950               free(buf);
13951               fclose(fp);
13952               MRIfree(&mri);
13953               errno = 0;
13954               ErrorReturn(NULL,
13955                           (ERROR_BADFILE,
13956                            "niiRead(): error reading from %s", fname));
13957             }
13958             if(swapped_flag)
13959               byteswapbuffloat(buf, bytes_per_voxel * mri->width);
13960             for(i = 0;i < mri->width;i++)
13961               MRIFseq_vox(mri, i, j, k, t) =
13962                 hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
13963           }
13964       free(buf);
13965     }
13966 
13967     if(hdr.datatype == DT_DOUBLE) {
13968       double *buf;
13969       unsigned char *cbuf, ccbuf[8];
13970       bytes_per_voxel = 8;
13971       buf = (double *)malloc(mri->width * bytes_per_voxel);
13972       for(t = 0;t < mri->nframes;t++)
13973         for(k = 0;k < mri->depth;k++)
13974           for(j = 0;j < mri->height;j++) {
13975             n_read = fread(buf, bytes_per_voxel, mri->width, fp);
13976             if(n_read != mri->width) {
13977               free(buf);
13978               fclose(fp);
13979               MRIfree(&mri);
13980               errno = 0;
13981               ErrorReturn(NULL,
13982                           (ERROR_BADFILE,
13983                            "niiRead(): error reading from %s", fname));
13984             }
13985             if(swapped_flag) {
13986               for(i = 0;i < mri->width;i++)
13987                 {
13988                   cbuf = (unsigned char *)&buf[i];
13989                   memcpy(ccbuf, cbuf, 8);
13990                   cbuf[0] = ccbuf[7];
13991                   cbuf[1] = ccbuf[6];
13992                   cbuf[2] = ccbuf[5];
13993                   cbuf[3] = ccbuf[4];
13994                   cbuf[4] = ccbuf[3];
13995                   cbuf[5] = ccbuf[2];
13996                   cbuf[6] = ccbuf[1];
13997                   cbuf[7] = ccbuf[0];
13998                 }
13999             }
14000             for(i = 0;i < mri->width;i++)
14001               MRIFseq_vox(mri, i, j, k, t) =
14002                 hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
14003           }
14004       free(buf);
14005     }
14006 
14007     if(hdr.datatype == DT_INT8) {
14008       char *buf;
14009       bytes_per_voxel = 1;
14010       buf = (char *)malloc(mri->width * bytes_per_voxel);
14011       for(t = 0;t < mri->nframes;t++)
14012         for(k = 0;k < mri->depth;k++)
14013           for(j = 0;j < mri->height;j++){
14014             n_read = fread(buf, bytes_per_voxel, mri->width, fp);
14015             if(n_read != mri->width) {
14016               free(buf);
14017               fclose(fp);
14018               MRIfree(&mri);
14019               errno = 0;
14020               ErrorReturn(NULL,
14021                           (ERROR_BADFILE,
14022                            "niiRead(): error reading from %s", fname));
14023             }
14024             for(i = 0;i < mri->width;i++)
14025               MRIFseq_vox(mri, i, j, k, t) =
14026                 hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
14027           }
14028       free(buf);
14029     }
14030 
14031     if(hdr.datatype == DT_UINT16) {
14032       unsigned short *buf;
14033       bytes_per_voxel = 2;
14034       buf = (unsigned short *)malloc(mri->width * bytes_per_voxel);
14035       for(t = 0;t < mri->nframes;t++)
14036         for(k = 0;k < mri->depth;k++)
14037           for(j = 0;j < mri->height;j++) {
14038             n_read = fread(buf, bytes_per_voxel, mri->width, fp);
14039             if(n_read != mri->width){
14040               free(buf);
14041               fclose(fp);
14042               MRIfree(&mri);
14043               errno = 0;
14044               ErrorReturn(NULL,
14045                           (ERROR_BADFILE,
14046                            "niiRead(): error reading from %s", fname));
14047             }
14048             if(swapped_flag)
14049               byteswapbufshort(buf, bytes_per_voxel * mri->width);
14050             for(i = 0;i < mri->width;i++)
14051               MRIFseq_vox(mri, i, j, k, t) =
14052                 hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
14053           }
14054       free(buf);
14055     }
14056 
14057     if(hdr.datatype == DT_UINT32) {
14058       unsigned int *buf;
14059       bytes_per_voxel = 4;
14060       buf = (unsigned int *)malloc(mri->width * bytes_per_voxel);
14061       for(t = 0;t < mri->nframes;t++)
14062         for(k = 0;k < mri->depth;k++)
14063           for(j = 0;j < mri->height;j++)
14064             {
14065               n_read = fread(buf, bytes_per_voxel, mri->width, fp);
14066               if(n_read != mri->width)
14067                 {
14068                   free(buf);
14069                   fclose(fp);
14070                   MRIfree(&mri);
14071                   errno = 0;
14072                   ErrorReturn(NULL,
14073                               (ERROR_BADFILE,
14074                                "niiRead(): error reading from %s", fname));
14075                 }
14076               if(swapped_flag)
14077                 byteswapbuffloat(buf, bytes_per_voxel * mri->width);
14078               for(i = 0;i < mri->width;i++)
14079                 MRIFseq_vox(mri, i, j, k, t) =
14080                   hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
14081             }
14082       free(buf);
14083     }
14084   }
14085   fclose(fp);
14086 
14087   return(mri);
14088 
14089 } /* end niiRead() */
14090 /*------------------------------------------------------------------
14091   niiWrite() - note: there is also an nifti1Write(). Make sure to
14092   edit both.
14093   -----------------------------------------------------------------*/
14094 static int niiWrite(MRI *mri, char *fname)
14095 {
14096 
14097   FILE *fp;
14098   int j, k, t;
14099   BUFTYPE *buf;
14100   struct nifti_1_header hdr;
14101   int error;
14102 
14103   memset(&hdr, 0x00, sizeof(hdr));
14104 
14105   hdr.sizeof_hdr = 348;
14106   hdr.dim_info = 0;
14107 
14108   if(mri->nframes == 1){
14109     hdr.dim[0] = 3;
14110     hdr.dim[1] = mri->width;
14111     hdr.dim[2] = mri->height;
14112     hdr.dim[3] = mri->depth;
14113     hdr.pixdim[1] = mri->xsize;
14114     hdr.pixdim[2] = mri->ysize;
14115     hdr.pixdim[3] = mri->zsize;
14116   }
14117   else{
14118     hdr.dim[0] = 4;
14119     hdr.dim[1] = mri->width;
14120     hdr.dim[2] = mri->height;
14121     hdr.dim[3] = mri->depth;
14122     hdr.dim[4] = mri->nframes;
14123     hdr.pixdim[1] = mri->xsize;
14124     hdr.pixdim[2] = mri->ysize;
14125     hdr.pixdim[3] = mri->zsize;
14126     hdr.pixdim[4] = mri->tr/1000.0; // see also xyzt_units
14127   }
14128 
14129   if(mri->type == MRI_UCHAR)
14130     {
14131       hdr.datatype = DT_UNSIGNED_CHAR;
14132       hdr.bitpix = 8;
14133     }
14134   else if(mri->type == MRI_INT)
14135     {
14136       hdr.datatype = DT_SIGNED_INT;
14137       hdr.bitpix = 32;
14138     }
14139   else if(mri->type == MRI_LONG)
14140     {
14141       hdr.datatype = DT_SIGNED_INT;
14142       hdr.bitpix = 32;
14143     }
14144   else if(mri->type == MRI_FLOAT)
14145     {
14146       hdr.datatype = DT_FLOAT;
14147       hdr.bitpix = 32;
14148     }
14149   else if(mri->type == MRI_SHORT)
14150     {
14151       hdr.datatype = DT_SIGNED_SHORT;
14152       hdr.bitpix = 16;
14153     }
14154   else if(mri->type == MRI_BITMAP)
14155     {
14156       ErrorReturn(ERROR_UNSUPPORTED,
14157                   (ERROR_UNSUPPORTED,
14158                    "niiWrite(): data type MRI_BITMAP unsupported"));
14159     }
14160   else if(mri->type == MRI_TENSOR)
14161     {
14162       ErrorReturn(ERROR_UNSUPPORTED,
14163                   (ERROR_UNSUPPORTED,
14164                    "niiWrite(): data type MRI_TENSOR unsupported"));
14165     }
14166   else
14167     {
14168       ErrorReturn(ERROR_BADPARM,
14169                   (ERROR_BADPARM,
14170                    "niiWrite(): unknown data type %d", mri->type));
14171     }
14172 
14173   hdr.intent_code = NIFTI_INTENT_NONE;
14174   hdr.intent_name[0] = '\0';
14175   hdr.vox_offset = sizeof(hdr);
14176   hdr.scl_slope = 0.0;
14177   hdr.slice_code = 0;
14178   hdr.xyzt_units = NIFTI_UNITS_MM | NIFTI_UNITS_SEC;
14179   hdr.cal_max = 0.0;
14180   hdr.cal_min = 0.0;
14181   hdr.toffset = 0;
14182 
14183   /* set the nifti header qform values */
14184   error = mriToNiftiQform(mri, &hdr);
14185   if(error != NO_ERROR)
14186     return(error);
14187 
14188   memcpy(hdr.magic, NII_MAGIC, 4);
14189 
14190   fp = fopen(fname, "w");
14191   if(fp == NULL)
14192     {
14193       errno = 0;
14194       ErrorReturn(ERROR_BADFILE,
14195                   (ERROR_BADFILE,
14196                    "niiWrite(): error opening file %s", fname));
14197     }
14198 
14199   if(fwrite(&hdr, sizeof(hdr), 1, fp) != 1)
14200     {
14201       fclose(fp);
14202       errno = 0;
14203       ErrorReturn(ERROR_BADFILE,
14204                   (ERROR_BADFILE,
14205                    "niiWrite(): error writing header to %s", fname));
14206     }
14207 
14208   for(t = 0;t < mri->nframes;t++)
14209     for(k = 0;k < mri->depth;k++)
14210       for(j = 0;j < mri->height;j++)
14211         {
14212           buf = &MRIseq_vox(mri, 0, j, k, t);
14213           if(fwrite(buf, hdr.bitpix/8, mri->width, fp) != mri->width)
14214             {
14215               fclose(fp);
14216               errno = 0;
14217               ErrorReturn(ERROR_BADFILE,
14218                           (ERROR_BADFILE,
14219                            "niiWrite(): error writing data to %s", fname));
14220             }
14221         }
14222 
14223   fclose(fp);
14224 
14225   return(NO_ERROR);
14226 
14227 } /* end niiWrite() */
14228 
14229 #endif

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.

You are not allowed to attach a file to this page.