Skip to content.

AFNI/NIfTI Server

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

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

nifti1_io.c

Go to the documentation of this file.
00001 #define _NIFTI1_IO_C_
00002 
00003 #include "nifti1_io.h"   /*** typedefs, prototypes, macros, etc. ***/
00004 
00005 /*****===================================================================*****/
00006 /*****     Sample functions to deal with NIFTI-1 and ANALYZE files       *****/
00007 /*****...................................................................*****/
00008 /*****            This code is released to the public domain.            *****/
00009 /*****...................................................................*****/
00010 /*****  Author: Robert W Cox, SSCC/DIRP/NIMH/NIH/DHHS/USA/EARTH          *****/
00011 /*****  Date:   August 2003                                              *****/
00012 /*****...................................................................*****/
00013 /*****  Neither the National Institutes of Health (NIH), nor any of its  *****/
00014 /*****  employees imply any warranty of usefulness of this software for  *****/
00015 /*****  any purpose, and do not assume any liability for damages,        *****/
00016 /*****  incidental or otherwise, caused by any use of this document.     *****/
00017 /*****===================================================================*****/
00018 
00019 
00020 /* global version and history strings, for printing */
00021 static char gni_version[] = "nifti library version 0.5 (December 14, 2004)";
00022 static char gni_history[] = 
00023   "----------------------------------------------------------------------\n"
00024   "history (of nifti library changes):\n"
00025   "\n"
00026   "0.0  August, 2003 [rwcox]\n"
00027   "     (Robert W Cox of the National Institutes of Health, SSCC/DIRP/NIMH)\n"
00028   "   - initial version\n"
00029   "\n"
00030   "0.1  July/August, 2004 [Mark Jenkinson]\n"
00031   "     (FMRIB Centre, University of Oxford, UK)\n"
00032   "   - Mainly adding low-level IO and changing things to allow gzipped\n"
00033   "     files to be read and written\n"
00034   "   - Full backwards compatability should have been maintained\n"
00035   "\n"
00036   "0.2  16 Nov 2004 [rickr]\n"
00037   "     (Rick Reynolds of the National Institutes of Health, SSCC/DIRP/NIMH)\n"
00038   "   - included Mark's changes in the AFNI distribution (including znzlib/)\n"
00039   "     (HAVE_ZLIB is commented out for the standard distribution)\n"
00040   "   - modified nifti_validfilename() and nifti_makebasename()\n"
00041   "   - added nifti_find_file_extension()\n"
00042   "\n"
00043   "0.3  3 Dec 2004 [rickr]\n"
00044   "   - note: header extensions are not yet checked for\n"
00045   "   - added formatted history as global string, for printing\n"
00046   "   - added nifti_disp_lib_hist(), to display the nifti library history\n"
00047   "   - added nifti_disp_lib_version(), to display the nifti library history\n"
00048   "   - re-wrote nifti_findhdrname()\n"
00049   "       o used nifti_find_file_extension()\n"
00050   "       o changed order of file tests (default is .nii, depends on input)\n"
00051   "       o free hdrname on failure\n"
00052   "   - made similar changes to nifti_findimgname()\n"
00053   "   - check for NULL return from nifti_findhdrname() calls\n"
00054   "   - removed most of ERREX() macros\n"
00055   "   - modified nifti_image_read()\n"
00056   "       o added debug info and error checking (on gni_debug > 0, only)\n"
00057   "       o fail if workingname is NULL\n"
00058   "       o check for failure to open header file\n"
00059   "       o free workingname on failure\n"
00060   "       o check for failure of nifti_image_load()\n"
00061   "       o check for failure of nifti_convert_nhdr2nim()\n"
00062   "   - changed nifti_image_load() to int, and check nifti_read_buffer return\n"
00063   "   - changed nifti_read_buffer() to fail on short read, and to count float\n"
00064   "     fixes (to print on debug)\n"
00065   "   - changed nifti_image_infodump to print to stderr\n"
00066   "   - updated function header comments, or moved comments above header\n"
00067   "   - removed const keyword\n"
00068   "   - added LNI_FERR() macro for error reporting on input files\n"
00069   "\n"
00070   "0.4  10 Dec 2004 [rickr]  - added header extensions\n"
00071   "   - in nifti1_io.h:\n"
00072   "       o added num_ext and ext_list to the definition of nifti_image\n"
00073   "       o made many functions static (more to follow)\n"
00074   "       o added LNI_MAX_NIA_EXT_LEN, for max nifti_type 3 extension length\n"
00075   "   - added __DATE__ to version output in nifti_disp_lib_version()\n"
00076   "   - added nifti_disp_matrix_orient() to print orientation information\n"
00077   "   - added '.nia' as a valid file extension in nifti_find_file_extension()\n"
00078   "   - added much more debug output\n"
00079   "   - in nifti_image_read(), in the case of an ASCII header, check for\n"
00080   "     extensions after the end of the header\n"
00081   "   - added nifti_read_extensions() function\n"
00082   "   - added nifti_read_next_extension() function\n"
00083   "   - added nifti_add_exten_to_list() function\n"
00084   "   - added nifti_valid_extension() function\n"
00085   "   - added nifti_write_extensions() function\n"
00086   "   - added nifti_extension_size() function\n"
00087   "   - in nifti_set_iname_offest():\n"
00088   "       o adjust offset by the extension size and the extender size\n"
00089   "       o fixed the 'ceiling modulo 16' computation\n"
00090   "   - in nifti_image_write_hdr_img2(): \n"
00091   "       o added extension writing\n"
00092   "       o check for NULL return from nifti_findimgname()\n"
00093   "   - include number of extensions in nifti_image_to_ascii() output\n"
00094   "   - in nifti_image_from_ascii():\n"
00095   "       o return bytes_read as a parameter, computed from the final spos\n"
00096   "       o extract num_ext from ASCII header\n"
00097   "\n"
00098   "0.5  14 Dec 2004 [rickr]  - added sub-brick reading functions\n"
00099   "   - added nifti_brick_list type to nifti1_io.h, along with new prototypes\n"
00100   "   - added main nifti_image_read_bricks() function, with description\n"
00101   "   - added nifti_image_load_bricks() - library function (requires nim)\n"
00102   "   - added valid_nifti_brick_list() - library function\n"
00103   "   - added free_NBL() - library function\n"
00104   "   - added update_nifti_image_for_brick_list() for dimension update\n"
00105   "   - added nifti_load_NBL_bricks(), nifti_alloc_NBL_mem(),\n"
00106   "           nifti_copynsort() and force_positive() (static functions)\n"
00107   "   - in nifti_image_read(), check for failed load only if read_data is set\n"
00108   "   - broke most of nifti_image_load() into nifti_image_load_prep()\n"
00109   "----------------------------------------------------------------------\n";
00110 
00111 /* global debug level */
00112 static int gni_debug = 0;
00113 
00114 /*---------------------------------------------------------------------------*/
00115 /* Return a pointer to a string holding the name of a NIFTI datatype.
00116    Don't free() or modify this string!  It points to static storage.
00117 -----------------------------------------------------------------------------*/
00118 
00119 /* for calling from some main program */
00120 void nifti_disp_lib_hist( void )
00121 {
00122    fputs(gni_history, stdout);
00123 }
00124 
00125 void nifti_disp_lib_version( void )
00126 {
00127    printf("%s, compiled %s\n", gni_version, __DATE__);
00128 }
00129 
00130 
00131 /*----------------------------------------------------------------------
00132  * nifti_image_read_bricks          - read nifti data as array of bricks
00133  *                                    13 Dec 2004 [rickr]
00134  * inputs:
00135  *          hname    - filename of dataset to read
00136  *                   - must be valid
00137  *          nbricks  - number of sub-bricks to read
00138  *                   - if blist is valid, nbricks must be > 0
00139  *          blist    - list of sub-bricks to read (can be NULL)
00140  *                   - if NULL, read complete dataset
00141  *          NBL      - pointer to empty nifti_brick_list struct
00142  *                   - must be a valid pointer
00143  *
00144  * return:
00145  *          nim      - same as nifti_image_read, but data is always NULL
00146  *          NBL      - filled with data
00147  *
00148  * By default, this function will read the nifti dataset and break the data
00149  * into a list of nt*nu*nv*nw sub-bricks, each having size nx*ny*nz elements.
00150  * That is to say, instead of reading the entire dataset as a single array,
00151  * break it up into sub-bricks, each of size nx*ny*nz elements.
00152  *
00153  * If 'blist' is valid, it is taken to be a list of sub-bricks, of length
00154  * 'nbricks'.  The data will still be separated into sub-bricks of size
00155  * nx*ny*nz elements, but now 'nbricks' sub-bricks will be returned, of the
00156  * caller's choosing via 'blist'.
00157  *
00158  * E.g. consider a dataset with 12 sub-bricks (numbered 0..11), and the
00159  * following code:
00160  *
00161  * { nifti_brick_list   NB_orig, NB_select;
00162  *   nifti_image      * nim_orig, * nim_select;
00163  *   int                blist[5] = { 7, 0, 5, 5, 9 };
00164  *
00165  *   nim_orig   = nifti_image_read_bricks("myfile.nii", 0, NULL,  &NB_orig);
00166  *   nim_select = nifti_image_read_bricks("myfile.nii", 5, blist, &NB_select);
00167  * }
00168  *
00169  * Here, nim_orig gets the entire dataset, where NB_orig.nbricks = 11.  But
00170  * nim_select has NB_select.nbricks = 5.
00171  *
00172  * Note that the first case is not quite the same as just calling the
00173  * nifti_image_read function, as here the data is separated into sub-bricks.
00174  *
00175  * Note that valid values for blist are in [0..nt*nu*nv*nw-1],
00176  * or written [ 0 .. (dim[4]*dim[5]*dim[6]*dim[7] - 1) ].
00177  *----------------------------------------------------------------------*/
00178 nifti_image *nifti_image_read_bricks( char *hname , int nbricks, int * blist,
00179                                       nifti_brick_list * NBL )
00180 {
00181    nifti_image * nim;
00182 
00183    if( !hname || !NBL ){
00184       fprintf(stderr,"** nifti_image_read_bricks: bad params (%p,%p)\n",
00185               hname, NBL);
00186       return NULL;
00187    }
00188 
00189    if( blist && nbricks <= 0 ){
00190       fprintf(stderr,"** nifti_image_read_bricks: bad nbricks, %d\n", nbricks);
00191       return NULL;
00192    }
00193 
00194    nim = nifti_image_read(hname, 0);  /* read header, but not data */
00195 
00196    if( !nim ) return NULL;   /* errors were already printed */
00197 
00198    /* if we fail, free image and return */
00199    if( nifti_image_load_bricks(nim, nbricks, blist, NBL) <= 0 ){
00200       nifti_image_free(nim);
00201       return NULL;
00202    }
00203 
00204    if( blist ) update_nifti_image_for_brick_list(nim, nbricks);
00205 
00206    return nim;
00207 }
00208 
00209 
00210 /*----------------------------------------------------------------------
00211  * update_nifti_image_for_brick_list  - update nifti_image
00212  *
00213  * When loading a specific brick list, the distinction between
00214  * nt, nu, nv and nw is lost.  So put everything in t, and set
00215  * dim[0] = 4.
00216  *----------------------------------------------------------------------*/
00217 static void update_nifti_image_for_brick_list( nifti_image * nim , int nbricks )
00218 {
00219    int ndim;
00220 
00221    if( gni_debug > 2 ){
00222       fprintf(stderr,"+d updating image dimensions for %d bricks in list\n",
00223               nbricks);
00224       fprintf(stderr,"   ndim = %d\n",nim->ndim);
00225       fprintf(stderr,"   nx,ny,nz,nt,nu,nv,nw: (%d,%d,%d,%d,%d,%d,%d)",
00226               nim->nx, nim->ny, nim->nz, nim->nt, nim->nu, nim->nv, nim->nw);
00227    }
00228 
00229    nim->nt = nbricks;
00230    nim->nu = nim->nv = nim->nw = 1;
00231 
00232    nim->dim[4] = nbricks;
00233    nim->dim[5] = nim->dim[6] = nim->dim[7] = 1;
00234 
00235    /* update the dimensions to 4 or lower */
00236    for( ndim = 4; (ndim > 1) && (nim->dim[ndim] <= 1); ndim-- )
00237        ;
00238    nim->dim[0] = nim->ndim = ndim;
00239 
00240    if( gni_debug > 2 ){
00241       fprintf(stderr," --> (%d,%d,%d,%d,%d,%d,%d)\n",
00242               nim->nx, nim->ny, nim->nz, nim->nt, nim->nu, nim->nv, nim->nw);
00243       fprintf(stderr,"+d new ndim = %d\n",nim->ndim);
00244    }
00245 }
00246 
00247 
00248 /*----------------------------------------------------------------------
00249  * Load the image data from disk into an already-prepared image struct.
00250  *                                                  13 Dec 2004 [rickr]
00251  * 
00252  * If blist is NULL, read the dataset normally.
00253  * 
00254  * return the number of loaded bricks (NBL->nbricks)
00255  *
00256  *  > 0 : success
00257  *    0 : failure
00258  *  < 0 : error
00259  *----------------------------------------------------------------------*/
00260 int nifti_image_load_bricks( nifti_image * nim , int nbricks, int * blist,
00261                              nifti_brick_list * NBL )
00262 {
00263    int     * slist = NULL, * sindex = NULL, rv;
00264    znzFile   fp;
00265 
00266    /* we can have blist == NULL */
00267    if( !nim || !NBL ){
00268       fprintf(stderr,"** nifti_image_load_bricks, bad params (%p,%p)\n",
00269               nim, NBL);
00270       return -1;
00271    }
00272 
00273    if( blist && ! valid_nifti_brick_list( nim, nbricks, blist, 1 ) )
00274       return -1;
00275 
00276    /* for efficiency, let's read the file in order */
00277    if( blist && nifti_copynsort( nbricks, blist, &slist, &sindex ) != 0 )
00278       return -1;
00279 
00280    /* open the file and position the FILE pointer */
00281    fp = nifti_image_load_prep( nim );
00282    if( !fp ){
00283       if( gni_debug > 0 )
00284          fprintf(stderr,"** nifti_image_load_bricks, failed load_prep\n");
00285       if( blist ){ free(slist); free(sindex); }
00286       return -1;
00287    }
00288 
00289    /* this will flag to allocate defaults */
00290    if( !blist ) nbricks = 0;
00291    if( nifti_alloc_NBL_mem( nim, nbricks, NBL ) != 0 ){
00292       if( blist ){ free(slist); free(sindex); }
00293       znzclose(fp);
00294       return -1;
00295    }
00296 
00297    rv = nifti_load_NBL_bricks(nim, slist, sindex, NBL, fp);
00298 
00299    if( rv != 0 ){
00300       free_NBL( NBL );  /* failure! */
00301       NBL->nbricks = 0; /* repetative, but clear */
00302    }
00303 
00304    if( slist ){ free(slist); free(sindex); }
00305 
00306    znzclose(fp);
00307 
00308    return NBL->nbricks;
00309 }
00310 
00311 
00312 /*----------------------------------------------------------------------
00313  * free_NBL      - free all pointers and clear structure
00314  *
00315  * note: this does not presume to free the structure pointer
00316  *----------------------------------------------------------------------*/
00317 void free_NBL( nifti_brick_list * NBL )
00318 {
00319    int c;
00320 
00321    if( NBL->bricks ){
00322       for( c = 0; c < NBL->nbricks; c++ )
00323          if( NBL->bricks[c] ) free(NBL->bricks[c]);
00324       free(NBL->bricks);
00325       NBL->bricks = NULL;
00326    }
00327 
00328    NBL->nbricks = NBL->bsize = 0;
00329 }
00330 
00331 
00332 /*----------------------------------------------------------------------
00333  * nifti_load_NBL_bricks      - read the file data into the NBL struct
00334  *
00335  * return 0 on success, -1 on failure
00336  *----------------------------------------------------------------------*/
00337 static int nifti_load_NBL_bricks( nifti_image * nim , int * slist, int * sindex,
00338                                   nifti_brick_list * NBL, znzFile fp )
00339 {
00340    int c, rv;
00341    int oposn, fposn;      /* orig and current file positions */
00342    int prev, isrc, idest; /* previous and current sub-brick, and new index */
00343 
00344    oposn = znztell(fp);  /* store current file position */
00345    fposn = oposn;
00346    if( fposn < 0 ){
00347       fprintf(stderr,"** load bricks: ztell failed??\n");
00348       return -1;
00349    }
00350 
00351    /* first, handle the default case, no passed blist */
00352    if( !slist ){
00353       for( c = 0; c < NBL->nbricks; c++ ) {
00354          rv = nifti_read_buffer(fp, NBL->bricks[c], NBL->bsize, nim);
00355          if( rv != NBL->bsize ){
00356             fprintf(stderr,"** load bricks: cannot read brick %d from '%s'\n",
00357                     c, nim->iname ? nim->iname : nim->fname);
00358             return -1;
00359          }
00360       }
00361       if( gni_debug > 1 )
00362          fprintf(stderr,"+d read %d default bricks from file %s\n",
00363                  NBL->nbricks, nim->iname ? nim->iname : nim->fname );
00364       return 0;
00365    }
00366 
00367    if( !sindex ){
00368       fprintf(stderr,"** load_NBL_bricks: missing index list\n");
00369       return -1;
00370    }
00371 
00372    prev = -1;   /* use prev for previous sub-brick */
00373    for( c = 0; c < NBL->nbricks; c++ ){
00374        isrc = slist[c];   /* this is original brick index (c is new one) */
00375        idest = sindex[c]; /* this is the destination index for this data */
00376 
00377        /* if this sub-brick is not the previous, we must read from disk */
00378        if( isrc != prev ){
00379 
00380           /* if we are not looking at the correct sub-brick, scan forward */
00381           if( fposn != (oposn + isrc*NBL->bsize) ){
00382              fposn = oposn + isrc*NBL->bsize;
00383              if( znzseek(fp, fposn, SEEK_SET) < 0 ){
00384                 fprintf(stderr,"** failed to locate brick %d in file '%s'\n",
00385                         isrc, nim->iname ? nim->iname : nim->fname);
00386                 return -1;
00387              }
00388           }
00389 
00390           /* only 10,000 lines later and we're actually reading something! */
00391           rv = nifti_read_buffer(fp, NBL->bricks[idest], NBL->bsize, nim);
00392           if( rv != NBL->bsize ){
00393              fprintf(stderr,"** failed to read brick %d from file '%s'\n",
00394                      isrc, nim->iname ? nim->iname : nim->fname);
00395              return -1;
00396           }
00397           fposn += NBL->bsize;
00398        } else {
00399           /* we have already read this sub-brick, just copy the previous one */
00400           /* note that this works because they are sorted */
00401           memcpy(NBL->bricks[idest], NBL->bricks[sindex[c-1]], NBL->bsize);
00402        }
00403 
00404        prev = isrc;  /* in any case, note the now previous sub-brick */
00405    }
00406 
00407    return 0;
00408 }
00409 
00410 
00411 /*----------------------------------------------------------------------
00412  * nifti_alloc_NBL_mem      - allocate memory for bricks
00413  *
00414  * return 0 on success, -1 on failure
00415  *----------------------------------------------------------------------*/
00416 static int nifti_alloc_NBL_mem(nifti_image * nim, int nbricks,
00417                                nifti_brick_list * nbl)
00418 {
00419    int c;
00420 
00421    /* if nbricks is not specified, use the default */
00422    if( nbricks > 0 ) nbl->nbricks = nbricks;
00423    else              nbl->nbricks = nim->nt * nim->nu * nim->nv * nim->nw;
00424 
00425    nbl->bsize   = nim->nx * nim->ny * nim->nz;
00426    nbl->bricks  = (void **)malloc(nbl->nbricks * sizeof(void *));
00427 
00428    if( ! nbl->bricks ){
00429       fprintf(stderr,"** NANM: failed to alloc %d void ptrs\n",nbricks);
00430       return -1;
00431    }
00432 
00433    for( c = 0; c < nbl->nbricks; c++ ){
00434       nbl->bricks[c] = (void *)malloc(nbl->bsize * nim->nbyper);
00435       if( ! nbl->bricks[c] ){
00436          fprintf(stderr,"** NANM: failed to alloc %d bytes for brick %d\n",
00437                  nbl->bsize*nim->nbyper, c);
00438          /* so free and clear everything before returning */
00439          while( c > 0 ){
00440             c--;
00441             free(nbl->bricks[c]);
00442          }
00443          free(nbl->bricks);
00444          nbl->bricks = NULL;
00445          nbl->nbricks = nbl->bsize = 0;
00446          return -1;
00447       }
00448    }
00449 
00450    if( gni_debug > 2 )
00451       fprintf(stderr,"+d NANM: alloc'd %d bricks of %d bytes for NBL\n",
00452               nbl->nbricks, nbl->bsize*nim->nbyper);
00453 
00454    return 0;
00455 }
00456 
00457 
00458 /*----------------------------------------------------------------------
00459  * nifti_copynsort      - copy int list, and sort with indices
00460  *
00461  * 1. duplicate the incoming list
00462  * 2. create an sindex list, and init with 0..nbricks-1
00463  * 3. do a slow insertion sort on the small slist, along with sindex list
00464  * 4. check results, just to be positive
00465  * 
00466  * So slist is sorted, and sindex hold original positions.
00467  *
00468  * return 0 on success, -1 on failure
00469  *----------------------------------------------------------------------*/
00470 static int nifti_copynsort(int nbricks, int * blist, int ** slist,
00471                            int ** sindex)
00472 {
00473    int * stmp, * itmp;   /* for ease of typing/reading */
00474    int   c1, c2, spos, tmp;
00475 
00476    *slist  = (int *)malloc(nbricks * sizeof(int));
00477    *sindex = (int *)malloc(nbricks * sizeof(int));
00478 
00479    if( !*slist || !*sindex ){
00480       fprintf(stderr,"** NCS: failed to alloc %d ints for sorting\n",nbricks);
00481       if(*slist)  free(*slist);   /* maybe one succeeded */
00482       if(*sindex) free(*sindex);
00483       return -1;
00484    }
00485 
00486    /* init the lists */
00487    memcpy(*slist, blist, nbricks*sizeof(int));
00488    for( c1 = 0; c1 < nbricks; c1++ ) (*sindex)[c1] = c1;
00489 
00490    /* now actually sort slist */
00491    stmp = *slist;
00492    itmp = *sindex;
00493    for( c1 = 0; c1 < nbricks-1; c1++ ) {
00494       /* find smallest value, init to current */
00495       spos = c1;
00496       for( c2 = c1+1; c2 < nbricks; c2++ )
00497          if( stmp[c2] < stmp[spos] ) spos = c2;
00498       if( spos != c1 ) /* swap: fine, don't maintain sub-order, see if I care */
00499       {
00500          tmp        = stmp[c1];      /* first swap the sorting values */
00501          stmp[c1]   = stmp[spos];
00502          stmp[spos] = tmp;
00503 
00504          tmp        = itmp[c1];      /* then swap the index values */
00505          itmp[c1]   = itmp[spos];
00506          itmp[spos] = tmp;
00507       }
00508    }
00509 
00510    if( gni_debug > 2 ){
00511       fprintf(stderr,  "+d sorted indexing list:\n");
00512       fprintf(stderr,  "  orig   : ");
00513       for( c1 = 0; c1 < nbricks; c1++ ) fprintf(stderr,"  %d",blist[c1]);
00514       fprintf(stderr,"\n  new    : ");
00515       for( c1 = 0; c1 < nbricks; c1++ ) fprintf(stderr,"  %d",stmp[c1]);
00516       fprintf(stderr,"\n  indices: ");
00517       for( c1 = 0; c1 < nbricks; c1++ ) fprintf(stderr,"  %d",itmp[c1]);
00518       fputc('\n', stderr);
00519    }
00520 
00521    /* check the sort (why not?  I've got time...) */
00522    for( c1 = 0; c1 < nbricks-1; c1++ ){
00523        if( (stmp[c1] > stmp[c1+1]) || (blist[itmp[c1]] != stmp[c1]) ){
00524           fprintf(stderr,"** sorting screw-up, way to go, rick!\n");
00525           free(stmp); free(itmp); *slist = NULL; *sindex = NULL;
00526           return -1;
00527        }
00528    }
00529 
00530    if( gni_debug > 2 ) fprintf(stderr,"-d sorting is okay\n");
00531 
00532    return 0;
00533 }
00534 
00535 
00536 /*----------------------------------------------------------------------
00537  * valid_nifti_brick_list      - check sub-brick list for image
00538  *
00539  * return 1 if valid, 0 if not
00540  *----------------------------------------------------------------------*/
00541 int valid_nifti_brick_list(nifti_image * nim , int nbricks, int * blist,
00542                            int disp_error)
00543 {
00544    int c, nsubs;
00545 
00546    if( !nim ){
00547       if( disp_error || gni_debug > 0 )
00548          fprintf(stderr,"** valid_nifti_brick_list: missing nifti image\n");
00549       return 0;
00550    }
00551 
00552    if( nbricks <= 0 || !blist ){
00553       if( disp_error || gni_debug > 1 )
00554          fprintf(stderr,"** valid_nifti_brick_list: no brick list to check\n");
00555       return 0;
00556    }
00557 
00558    /* nsubs sub-brick is nt*nu*nv*nw */
00559    nsubs = nim->dim[4] * nim->dim[5] * nim->dim[6] * nim->dim[7];
00560 
00561    if( nsubs <= 0 ){
00562       fprintf(stderr,"** VNBL warning: bad dim list (%d,%d,%d,%d)\n",
00563                      nim->dim[4], nim->dim[5], nim->dim[6], nim->dim[7]);
00564       int_force_positive(nim->dim+4, 4);
00565       nsubs = nim->dim[4] * nim->dim[5] * nim->dim[6] * nim->dim[7];
00566    }
00567 
00568    for( c = 0; c < nbricks; c++ )
00569       if( (blist[c] < 0) || (blist[c] >= nsubs) ){
00570          if( disp_error || gni_debug > 1 )
00571             fprintf(stderr,
00572                "-d ** bad sub-brick chooser %d (#%d), valid range is [0,%d]\n",
00573                blist[c], c, nsubs-1);
00574          return 0;
00575       }
00576 
00577    return 1;  /* all is well */
00578 }
00579 
00580 /* set any non-positive values to 1 */
00581 static int int_force_positive( int * list, int nel )
00582 {
00583    int c;
00584    if( *list || nel <= 0 ){
00585       if( gni_debug > 0 )
00586          fprintf(stderr,"** int_force_positive: bad params (%p,%d)\n",list,nel);
00587       return -1;
00588    }
00589    for( c = 0; c < nel; c++ )
00590       if( list[c] <= 0 ) list[c] = 1;
00591    return 0;
00592 }
00593 /* end of new nifti_image_read_bricks() functionality */
00594 
00595 /*----------------------------------------------------------------------
00596  * display the orientation from the quaternian fields
00597  *
00598  * return < 0 if results cannot be determined, 0 if okay
00599  *----------------------------------------------------------------------*/
00600 int nifti_disp_matrix_orient( char * mesg, mat44 mat )
00601 {
00602    int i, j, k;
00603 
00604    if ( mesg ) fputs( mesg, stderr );  /* use stdout? */
00605 
00606    mat44_to_orientation( mat, &i,&j,&k );
00607    if ( i <= 0 || j <= 0 || k <= 0 ) return -1;
00608 
00609    /* so we have good codes */
00610    fprintf(stderr, "  i orientation = '%s'\n"
00611                    "  j orientation = '%s'\n"
00612                    "  k orientation = '%s'\n",
00613                    nifti_orientation_string(i),
00614                    nifti_orientation_string(j),
00615                    nifti_orientation_string(k) );
00616    return 0;
00617 }
00618 
00619 
00620 char *nifti_strdup(char *str)
00621 {
00622   char *dup= (char *)malloc( strlen(str)+1 );
00623   if (dup) strcpy(dup,str);
00624   return dup;
00625 }
00626 #ifndef HAVE_STRDUP
00627 #endif
00628 
00629 
00630 char *nifti_datatype_string( int dt )
00631 {
00632    switch( dt ){
00633      case DT_UNKNOWN:    return "UNKNOWN"    ;
00634      case DT_BINARY:     return "BINARY"     ;
00635      case DT_INT8:       return "INT8"       ;
00636      case DT_UINT8:      return "UINT8"      ;
00637      case DT_INT16:      return "INT16"      ;
00638      case DT_UINT16:     return "UINT16"     ;
00639      case DT_INT32:      return "INT32"      ;
00640      case DT_UINT32:     return "UINT32"     ;
00641      case DT_INT64:      return "INT64"      ;
00642      case DT_UINT64:     return "UINT64"     ;
00643      case DT_FLOAT32:    return "FLOAT32"    ;
00644      case DT_FLOAT64:    return "FLOAT64"    ;
00645      case DT_FLOAT128:   return "FLOAT128"   ;
00646      case DT_COMPLEX64:  return "COMPLEX64"  ;
00647      case DT_COMPLEX128: return "COMPLEX128" ;
00648      case DT_COMPLEX256: return "COMPLEX256" ;
00649      case DT_RGB24:      return "RGB24"      ;
00650    }
00651    return "**ILLEGAL**" ;
00652 }
00653 
00654 /*---------------------------------------------------------------------------*/
00655 /* Determine if the datatype code dt is an integer type (1=YES, 0=NO).
00656 -----------------------------------------------------------------------------*/
00657 
00658 int nifti_is_inttype( int dt )
00659 {
00660    switch( dt ){
00661      case DT_UNKNOWN:    return 0 ;
00662      case DT_BINARY:     return 0 ;
00663      case DT_INT8:       return 1 ;
00664      case DT_UINT8:      return 1 ;
00665      case DT_INT16:      return 1 ;
00666      case DT_UINT16:     return 1 ;
00667      case DT_INT32:      return 1 ;
00668      case DT_UINT32:     return 1 ;
00669      case DT_INT64:      return 1 ;
00670      case DT_UINT64:     return 1 ;
00671      case DT_FLOAT32:    return 0 ;
00672      case DT_FLOAT64:    return 0 ;
00673      case DT_FLOAT128:   return 0 ;
00674      case DT_COMPLEX64:  return 0 ;
00675      case DT_COMPLEX128: return 0 ;
00676      case DT_COMPLEX256: return 0 ;
00677      case DT_RGB24:      return 1 ;
00678    }
00679    return 0 ;
00680 }
00681 
00682 /*---------------------------------------------------------------------------*/
00683 /* Return a pointer to a string holding the name of a NIFTI units type.
00684    Don't free() or modify this string!  It points to static storage.
00685 -----------------------------------------------------------------------------*/
00686 
00687 char *nifti_units_string( int uu )
00688 {
00689    switch( uu ){
00690      case NIFTI_UNITS_METER:  return "m" ;
00691      case NIFTI_UNITS_MM:     return "mm" ;
00692      case NIFTI_UNITS_MICRON: return "um" ;
00693      case NIFTI_UNITS_SEC:    return "s" ;
00694      case NIFTI_UNITS_MSEC:   return "ms" ;
00695      case NIFTI_UNITS_USEC:   return "us" ;
00696      case NIFTI_UNITS_HZ:     return "Hz" ;
00697      case NIFTI_UNITS_PPM:    return "ppm" ;
00698      case NIFTI_UNITS_RADS:   return "rad/s" ;
00699    }
00700    return "Unknown" ;
00701 }
00702 
00703 /*---------------------------------------------------------------------------*/
00704 /* Return a pointer to a string holding the name of a NIFTI transform type.
00705    Don't free() or modify this string!  It points to static storage.
00706 -----------------------------------------------------------------------------*/
00707 
00708 char *nifti_xform_string( int xx )
00709 {
00710    switch( xx ){
00711      case NIFTI_XFORM_SCANNER_ANAT:  return "Scanner Anat" ;
00712      case NIFTI_XFORM_ALIGNED_ANAT:  return "Aligned Anat" ;
00713      case NIFTI_XFORM_TALAIRACH:     return "Talairach" ;
00714      case NIFTI_XFORM_MNI_152:       return "MNI_152" ;
00715    }
00716    return "Unknown" ;
00717 }
00718 
00719 /*---------------------------------------------------------------------------*/
00720 /* Return a pointer to a string holding the name of a NIFTI intent type.
00721    Don't free() or modify this string!  It points to static storage.
00722 -----------------------------------------------------------------------------*/
00723 
00724 char *nifti_intent_string( int ii )
00725 {
00726    switch( ii ){
00727      case NIFTI_INTENT_CORREL:     return "Correlation statistic" ;
00728      case NIFTI_INTENT_TTEST:      return "T-statistic" ;
00729      case NIFTI_INTENT_FTEST:      return "F-statistic" ;
00730      case NIFTI_INTENT_ZSCORE:     return "Z-score"     ;
00731      case NIFTI_INTENT_CHISQ:      return "Chi-squared distribution" ;
00732      case NIFTI_INTENT_BETA:       return "Beta distribution" ;
00733      case NIFTI_INTENT_BINOM:      return "Binomial distribution" ;
00734      case NIFTI_INTENT_GAMMA:      return "Gamma distribution" ;
00735      case NIFTI_INTENT_POISSON:    return "Poisson distribution" ;
00736      case NIFTI_INTENT_NORMAL:     return "Normal distribution" ;
00737      case NIFTI_INTENT_FTEST_NONC: return "F-statistic noncentral" ;
00738      case NIFTI_INTENT_CHISQ_NONC: return "Chi-squared noncentral" ;
00739      case NIFTI_INTENT_LOGISTIC:   return "Logistic distribution" ;
00740      case NIFTI_INTENT_LAPLACE:    return "Laplace distribution" ;
00741      case NIFTI_INTENT_UNIFORM:    return "Uniform distribition" ;
00742      case NIFTI_INTENT_TTEST_NONC: return "T-statistic noncentral" ;
00743      case NIFTI_INTENT_WEIBULL:    return "Weibull distribution" ;
00744      case NIFTI_INTENT_CHI:        return "Chi distribution" ;
00745      case NIFTI_INTENT_INVGAUSS:   return "Inverse Gaussian distribution" ;
00746      case NIFTI_INTENT_EXTVAL:     return "Extreme Value distribution" ;
00747      case NIFTI_INTENT_PVAL:       return "P-value" ;
00748 
00749      case NIFTI_INTENT_LOGPVAL:    return "Log P-value" ;
00750      case NIFTI_INTENT_LOG10PVAL:  return "Log10 P-value" ;
00751 
00752      case NIFTI_INTENT_ESTIMATE:   return "Estimate" ;
00753      case NIFTI_INTENT_LABEL:      return "Label index" ;
00754      case NIFTI_INTENT_NEURONAME:  return "NeuroNames index" ;
00755      case NIFTI_INTENT_GENMATRIX:  return "General matrix" ;
00756      case NIFTI_INTENT_SYMMATRIX:  return "Symmetric matrix" ;
00757      case NIFTI_INTENT_DISPVECT:   return "Displacement vector" ;
00758      case NIFTI_INTENT_VECTOR:     return "Vector" ;
00759      case NIFTI_INTENT_POINTSET:   return "Pointset" ;
00760      case NIFTI_INTENT_TRIANGLE:   return "Triangle" ;
00761      case NIFTI_INTENT_QUATERNION: return "Quaternion" ;
00762 
00763      case NIFTI_INTENT_DIMLESS:    return "Dimensionless number" ;
00764    }
00765    return "Unknown" ;
00766 }
00767 
00768 /*---------------------------------------------------------------------------*/
00769 /* Return a pointer to a string holding the name of a NIFTI slice_code
00770    string.  Don't free() or modify this string!  It points to static storage.
00771 -----------------------------------------------------------------------------*/
00772 
00773 char *nifti_slice_string( int ss )
00774 {
00775    switch( ss ){
00776      case NIFTI_SLICE_SEQ_INC: return "sequential_increasing"  ;
00777      case NIFTI_SLICE_SEQ_DEC: return "sequential_decreasing"  ;
00778      case NIFTI_SLICE_ALT_INC: return "alternating_increasing" ;
00779      case NIFTI_SLICE_ALT_DEC: return "alternating_decreasing" ;
00780    }
00781    return "Unknown" ;
00782 }
00783 
00784 /*---------------------------------------------------------------------------*/
00785 /* Return a pointer to a string holding the name of a NIFTI orientation
00786    string.  Don't free() or modify this string!  It points to static storage.
00787 -----------------------------------------------------------------------------*/
00788 
00789 char *nifti_orientation_string( int ii )
00790 {
00791    switch( ii ){
00792      case NIFTI_L2R: return "Left-to-Right" ;
00793      case NIFTI_R2L: return "Right-to-Left" ;
00794      case NIFTI_P2A: return "Posterior-to-Anterior" ;
00795      case NIFTI_A2P: return "Anterior-to-Posterior" ;
00796      case NIFTI_I2S: return "Inferior-to-Superior" ;
00797      case NIFTI_S2I: return "Superior-to-Inferior" ;
00798    }
00799    return "Unknown" ;
00800 }
00801 
00802 /*--------------------------------------------------------------------------*/
00803 /* Given a datatype code, set number of bytes per voxel and the swapsize.
00804    The swapsize is set to 0 if this datatype doesn't ever need swapping.
00805 ----------------------------------------------------------------------------*/
00806 
00807 void nifti_datatype_sizes( int datatype , int *nbyper, int *swapsize )
00808 {
00809    int nb=0, ss=0 ;
00810    switch( datatype ){
00811      case DT_INT8:
00812      case DT_UINT8:       nb =  1 ; ss =  0 ; break ;
00813 
00814      case DT_INT16:
00815      case DT_UINT16:      nb =  2 ; ss =  2 ; break ;
00816 
00817      case DT_RGB24:       nb =  3 ; ss =  0 ; break ;
00818 
00819      case DT_INT32:
00820      case DT_UINT32:
00821      case DT_FLOAT32:     nb =  4 ; ss =  4 ; break ;
00822 
00823      case DT_COMPLEX64:   nb =  8 ; ss =  4 ; break ;
00824 
00825      case DT_FLOAT64:
00826      case DT_INT64:
00827      case DT_UINT64:      nb =  8 ; ss =  8 ; break ;
00828 
00829      case DT_FLOAT128:    nb = 16 ; ss = 16 ; break ;
00830 
00831      case DT_COMPLEX128:  nb = 16 ; ss =  8 ; break ;
00832 
00833      case DT_COMPLEX256:  nb = 32 ; ss = 16 ; break ;
00834    }
00835 
00836    ASSIF(nbyper,nb) ; ASSIF(swapsize,ss) ; return ;
00837 }
00838 
00839 /*---------------------------------------------------------------------------*/
00840 /* Given the quaternion parameters (etc.), compute a transformation matrix.
00841    See comments in nifti1.h for details.
00842      - qb,qc,qd = quaternion parameters
00843      - qx,qy,qz = offset parameters
00844      - dx,dy,dz = grid stepsizes (non-negative inputs are set to 1.0)
00845      - qfac     = sign of dz step (< 0 is negative; >= 0 is positive)
00846    If qx=qy=qz=0, dx=dy=dz=1, then the output is a rotation matrix.
00847    For qfac >= 0, the rotation is proper.
00848    For qfac <  0, the rotation is improper.
00849 -----------------------------------------------------------------------------*/
00850 
00851 mat44 quatern_to_mat44( float qb, float qc, float qd,
00852                         float qx, float qy, float qz,
00853                         float dx, float dy, float dz, float qfac )
00854 {
00855    mat44 R ;
00856    double a,b=qb,c=qc,d=qd , xd,yd,zd ;
00857 
00858    /* last row is always [ 0 0 0 1 ] */
00859 
00860    R.m[3][0]=R.m[3][1]=R.m[3][2] = 0.0 ; R.m[3][3]= 1.0 ;
00861 
00862    /* compute a parameter from b,c,d */
00863 
00864    a = 1.0l - (b*b + c*c + d*d) ;
00865    if( a < 1.e-7l ){                   /* special case */
00866      a = 1.0l / sqrt(b*b+c*c+d*d) ;
00867      b *= a ; c *= a ; d *= a ;        /* normalize (b,c,d) vector */
00868      a = 0.0l ;                        /* a = 0 ==> 180 degree rotation */
00869    } else{
00870      a = sqrt(a) ;                     /* angle = 2*arccos(a) */
00871    }
00872 
00873    /* load rotation matrix, including scaling factors for voxel sizes */
00874 
00875    xd = (dx > 0.0) ? dx : 1.0l ;       /* make sure are positive */
00876    yd = (dy > 0.0) ? dy : 1.0l ;
00877    zd = (dz > 0.0) ? dz : 1.0l ;
00878 
00879    if( qfac < 0.0 ) zd = -zd ;         /* left handedness? */
00880 
00881    R.m[0][0] =        (a*a+b*b-c*c-d*d) * xd ;
00882    R.m[0][1] = 2.0l * (b*c-a*d        ) * yd ;
00883    R.m[0][2] = 2.0l * (b*d+a*c        ) * zd ;
00884    R.m[1][0] = 2.0l * (b*c+a*d        ) * xd ;
00885    R.m[1][1] =        (a*a+c*c-b*b-d*d) * yd ;
00886    R.m[1][2] = 2.0l * (c*d-a*b        ) * zd ;
00887    R.m[2][0] = 2.0l * (b*d-a*c        ) * xd ;
00888    R.m[2][1] = 2.0l * (c*d+a*b        ) * yd ;
00889    R.m[2][2] =        (a*a+d*d-c*c-b*b) * zd ;
00890 
00891    /* load offsets */
00892 
00893    R.m[0][3] = qx ; R.m[1][3] = qy ; R.m[2][3] = qz ;
00894 
00895    return R ;
00896 }
00897 
00898 /*---------------------------------------------------------------------------*/
00899 /* Given the 3x4 upper corner of the matrix R, compute the quaternion
00900    parameters that fit it.  See comments in nifti1.h for details.
00901      - Any NULL pointer on input won't get assigned (e.g., if you don't want
00902        dx,dy,dz, just pass NULL in for those pointers).
00903      - If the 3 input matrix columns are NOT orthogonal, they will be
00904        orthogonalized prior to calculating the parameters, using
00905        the polar decomposition to find the orthogonal matrix closest
00906        to the column-normalized input matrix.
00907      - However, if the 3 input matrix columns are NOT orthogonal, then
00908        the matrix produced by quatern_to_mat44 WILL have orthogonal
00909        columns, so it won't be the same as the matrix input here.
00910        This "feature" is because the NIFTI 'qform' transform is
00911        deliberately not fully general -- it is intended to model a volume
00912        with perpendicular axes.
00913      - If the 3 input matrix columns are not even linearly independent,
00914        you'll just have to take your luck, won't you?
00915 -----------------------------------------------------------------------------*/
00916 
00917 void mat44_to_quatern( mat44 R ,
00918                        float *qb, float *qc, float *qd,
00919                        float *qx, float *qy, float *qz,
00920                        float *dx, float *dy, float *dz, float *qfac )
00921 {
00922    double r11,r12,r13 , r21,r22,r23 , r31,r32,r33 ;
00923    double xd,yd,zd , a,b,c,d ;
00924    mat33 P,Q ;
00925 
00926    /* offset outputs are read write out of input matrix  */
00927 
00928    ASSIF(qx,R.m[0][3]) ; ASSIF(qy,R.m[1][3]) ; ASSIF(qz,R.m[2][3]) ;
00929 
00930    /* load 3x3 matrix into local variables */
00931 
00932    r11 = R.m[0][0] ; r12 = R.m[0][1] ; r13 = R.m[0][2] ;
00933    r21 = R.m[1][0] ; r22 = R.m[1][1] ; r23 = R.m[1][2] ;
00934    r31 = R.m[2][0] ; r32 = R.m[2][1] ; r33 = R.m[2][2] ;
00935 
00936    /* compute lengths of each column; these determine grid spacings  */
00937 
00938    xd = sqrt( r11*r11 + r21*r21 + r31*r31 ) ;
00939    yd = sqrt( r12*r12 + r22*r22 + r32*r32 ) ;
00940    zd = sqrt( r13*r13 + r23*r23 + r33*r33 ) ;
00941 
00942    /* if a column length is zero, patch the trouble */
00943 
00944    if( xd == 0.0l ){ r11 = 1.0l ; r21 = r31 = 0.0l ; xd = 1.0l ; }
00945    if( yd == 0.0l ){ r22 = 1.0l ; r12 = r32 = 0.0l ; yd = 1.0l ; }
00946    if( zd == 0.0l ){ r33 = 1.0l ; r13 = r23 = 0.0l ; zd = 1.0l ; }
00947 
00948    /* assign the output lengths */
00949 
00950    ASSIF(dx,xd) ; ASSIF(dy,yd) ; ASSIF(dz,zd) ;
00951 
00952    /* normalize the columns */
00953 
00954    r11 /= xd ; r21 /= xd ; r31 /= xd ;
00955    r12 /= yd ; r22 /= yd ; r32 /= yd ;
00956    r13 /= zd ; r23 /= zd ; r33 /= zd ;
00957 
00958    /* At this point, the matrix has normal columns, but we have to allow
00959       for the fact that the hideous user may not have given us a matrix
00960       with orthogonal columns.
00961 
00962       So, now find the orthogonal matrix closest to the current matrix.
00963 
00964       One reason for using the polar decomposition to get this
00965       orthogonal matrix, rather than just directly orthogonalizing
00966       the columns, is so that inputting the inverse matrix to R
00967       will result in the inverse orthogonal matrix at this point.
00968       If we just orthogonalized the columns, this wouldn't necessarily hold. */
00969 
00970    Q.m[0][0] = r11 ; Q.m[0][1] = r12 ; Q.m[0][2] = r13 ; /* load Q */
00971    Q.m[1][0] = r21 ; Q.m[1][1] = r22 ; Q.m[1][2] = r23 ;
00972    Q.m[2][0] = r31 ; Q.m[2][1] = r32 ; Q.m[2][2] = r33 ;
00973 
00974    P = mat33_polar(Q) ;  /* P is orthog matrix closest to Q */
00975 
00976    r11 = P.m[0][0] ; r12 = P.m[0][1] ; r13 = P.m[0][2] ; /* unload */
00977    r21 = P.m[1][0] ; r22 = P.m[1][1] ; r23 = P.m[1][2] ;
00978    r31 = P.m[2][0] ; r32 = P.m[2][1] ; r33 = P.m[2][2] ;
00979 
00980    /*                            [ r11 r12 r13 ]               */
00981    /* at this point, the matrix  [ r21 r22 r23 ] is orthogonal */
00982    /*                            [ r31 r32 r33 ]               */
00983 
00984    /* compute the determinant to determine if it is proper */
00985 
00986    zd = r11*r22*r33-r11*r32*r23-r21*r12*r33
00987        +r21*r32*r13+r31*r12*r23-r31*r22*r13 ;  /* should be -1 or 1 */
00988 
00989    if( zd > 0 ){             /* proper */
00990      ASSIF(qfac,1.0) ;
00991    } else {                  /* improper ==> flip 3rd column */
00992      ASSIF(qfac,-1.0) ;
00993      r13 = -r13 ; r23 = -r23 ; r33 = -r33 ;
00994    }
00995 
00996    /* now, compute quaternion parameters */
00997 
00998    a = r11 + r22 + r33 + 1.0l ;
00999 
01000    if( a > 0.5l ){                /* simplest case */
01001      a = 0.5l * sqrt(a) ;
01002      b = 0.25l * (r32-r23) / a ;
01003      c = 0.25l * (r13-r31) / a ;
01004      d = 0.25l * (r21-r12) / a ;
01005    } else {                       /* trickier case */
01006      xd = 1.0 + r11 - (r22+r33) ;  /* 4*b*b */
01007      yd = 1.0 + r22 - (r11+r33) ;  /* 4*c*c */
01008      zd = 1.0 + r33 - (r11+r22) ;  /* 4*d*d */
01009      if( xd > 1.0 ){
01010        b = 0.5l * sqrt(xd) ;
01011        c = 0.25l* (r12+r21) / b ;
01012        d = 0.25l* (r13+r31) / b ;
01013        a = 0.25l* (r32-r23) / b ;
01014      } else if( yd > 1.0 ){
01015        c = 0.5l * sqrt(yd) ;
01016        b = 0.25l* (r12+r21) / c ;
01017        d = 0.25l* (r23+r32) / c ;
01018        a = 0.25l* (r13-r31) / c ;
01019      } else {
01020        d = 0.5l * sqrt(zd) ;
01021        b = 0.25l* (r13+r31) / d ;
01022        c = 0.25l* (r23+r32) / d ;
01023        a = 0.25l* (r21-r12) / d ;
01024      }
01025      if( a < 0.0l ){ b=-b ; c=-c ; d=-d; a=-a; }
01026    }
01027 
01028    ASSIF(qb,b) ; ASSIF(qc,c) ; ASSIF(qd,d) ;
01029    return ;
01030 }
01031 
01032 /*---------------------------------------------------------------------------*/
01033 /* Compute the inverse of a bordered 4x4 matrix.
01034    Some numerical code fragments were generated by Maple 8.
01035    If a singular matrix is input, the output matrix will be all zero.
01036    You can check for this by examining the [3][3] element, which will
01037    be 1.0 for the normal case and 0.0 for the bad case.
01038 -----------------------------------------------------------------------------*/
01039 
01040 mat44 mat44_inverse( mat44 R )
01041 {
01042    double r11,r12,r13,r21,r22,r23,r31,r32,r33,v1,v2,v3 , deti ;
01043    mat44 Q ;
01044                                                        /** INPUT MATRIX IS: **/
01045    r11 = R.m[0][0]; r12 = R.m[0][1]; r13 = R.m[0][2];  /* [ r11 r12 r13 v1 ] */
01046    r21 = R.m[1][0]; r22 = R.m[1][1]; r23 = R.m[1][2];  /* [ r21 r22 r23 v2 ] */
01047    r31 = R.m[2][0]; r32 = R.m[2][1]; r33 = R.m[2][2];  /* [ r31 r32 r33 v3 ] */
01048    v1  = R.m[0][3]; v2  = R.m[1][3]; v3  = R.m[2][3];  /* [  0   0   0   1 ] */
01049 
01050    deti = r11*r22*r33-r11*r32*r23-r21*r12*r33
01051          +r21*r32*r13+r31*r12*r23-r31*r22*r13 ;
01052 
01053    if( deti != 0.0l ) deti = 1.0l / deti ;
01054 
01055    Q.m[0][0] = deti*( r22*r33-r32*r23) ;
01056    Q.m[0][1] = deti*(-r12*r33+r32*r13) ;
01057    Q.m[0][2] = deti*( r12*r23-r22*r13) ;
01058    Q.m[0][3] = deti*(-r12*r23*v3+r12*v2*r33+r22*r13*v3
01059                      -r22*v1*r33-r32*r13*v2+r32*v1*r23) ;
01060 
01061    Q.m[1][0] = deti*(-r21*r33+r31*r23) ;
01062    Q.m[1][1] = deti*( r11*r33-r31*r13) ;
01063    Q.m[1][2] = deti*(-r11*r23+r21*r13) ;
01064    Q.m[1][3] = deti*( r11*r23*v3-r11*v2*r33-r21*r13*v3
01065                      +r21*v1*r33+r31*r13*v2-r31*v1*r23) ;
01066 
01067    Q.m[2][0] = deti*( r21*r32-r31*r22) ;
01068    Q.m[2][1] = deti*(-r11*r32+r31*r12) ;
01069    Q.m[2][2] = deti*( r11*r22-r21*r12) ;
01070    Q.m[2][3] = deti*(-r11*r22*v3+r11*r32*v2+r21*r12*v3
01071                      -r21*r32*v1-r31*r12*v2+r31*r22*v1) ;
01072 
01073    Q.m[3][0] = Q.m[3][1] = Q.m[3][2] = 0.0l ;
01074    Q.m[3][3] = (deti == 0.0l) ? 0.0l : 1.0l ; /* failure flag if deti == 0 */
01075 
01076    return Q ;
01077 }
01078 
01079 /*---------------------------------------------------------------------------*/
01080 /* Input 9 floats and make an orthgonal mat44 out of them.
01081    Each row is normalized, then mat33_polar() is used to orthogonalize them.
01082    If row #3 (r31,r32,r33) is input as zero, then it will be taken to be
01083    the cross product of rows #1 and #2.
01084 
01085    This function can be used to create a rotation matrix for transforming
01086    an oblique volume to anatomical coordinates.  For this application:
01087     - row #1 (r11,r12,r13) is the direction vector along the image i-axis
01088     - row #2 (r21,r22,r23) is the direction vector along the image j-axis
01089     - row #3 (r31,r32,r33) is the direction vector along the slice direction
01090       (if available; otherwise enter it as 0's)
01091    The first 2 rows can be taken from the DICOM attribute (0020,0037)
01092    "Image Orientation (Patient)".
01093 
01094    After forming the rotation matrix, the complete affine transformation from
01095    (i,j,k) grid indexes to (x,y,z) spatial coordinates can be computed by
01096    multiplying each column by the appropriate grid spacing:
01097     - column #1 (R.m[0][0],R.m[1][0],R.m[2][0]) by delta-x
01098     - column #2 (R.m[0][1],R.m[1][1],R.m[2][1]) by delta-y
01099     - column #3 (R.m[0][2],R.m[1][2],R.m[2][2]) by delta-z
01100    And by placing the center (x,y,z) coordinates of voxel (0,0,0) into
01101    the column #4 (R.m[0][3],R.m[1][3],R.m[2][3]).
01102 -----------------------------------------------------------------------------*/
01103 
01104 mat44 make_orthog_mat44( float r11, float r12, float r13 ,
01105                          float r21, float r22, float r23 ,
01106                          float r31, float r32, float r33  )
01107 {
01108    mat44 R ;
01109    mat33 Q , P ;
01110    double val ;
01111 
01112    R.m[3][0] = R.m[3][1] = R.m[3][2] = 0.0l ; R.m[3][3] = 1.0l ;
01113 
01114    Q.m[0][0] = r11 ; Q.m[0][1] = r12 ; Q.m[0][2] = r13 ; /* load Q */
01115    Q.m[1][0] = r21 ; Q.m[1][1] = r22 ; Q.m[1][2] = r23 ;
01116    Q.m[2][0] = r31 ; Q.m[2][1] = r32 ; Q.m[2][2] = r33 ;
01117 
01118    /* normalize row 1 */
01119 
01120    val = Q.m[0][0]*Q.m[0][0] + Q.m[0][1]*Q.m[0][1] + Q.m[0][2]*Q.m[0][2] ;
01121    if( val > 0.0l ){
01122      val = 1.0l / sqrt(val) ;
01123      Q.m[0][0] *= val ; Q.m[0][1] *= val ; Q.m[0][2] *= val ;
01124    } else {
01125      Q.m[0][0] = 1.0l ; Q.m[0][1] = 0.0l ; Q.m[0][2] = 0.0l ;
01126    }
01127 
01128    /* normalize row 2 */
01129 
01130    val = Q.m[1][0]*Q.m[1][0] + Q.m[1][1]*Q.m[1][1] + Q.m[1][2]*Q.m[1][2] ;
01131    if( val > 0.0l ){
01132      val = 1.0l / sqrt(val) ;
01133      Q.m[1][0] *= val ; Q.m[1][1] *= val ; Q.m[1][2] *= val ;
01134    } else {
01135      Q.m[1][0] = 0.0l ; Q.m[1][1] = 1.0l ; Q.m[1][2] = 0.0l ;
01136    }
01137 
01138    /* normalize row 3 */
01139 
01140    val = Q.m[2][0]*Q.m[2][0] + Q.m[2][1]*Q.m[2][1] + Q.m[2][2]*Q.m[2][2] ;
01141    if( val > 0.0l ){
01142      val = 1.0l / sqrt(val) ;
01143      Q.m[2][0] *= val ; Q.m[2][1] *= val ; Q.m[2][2] *= val ;
01144    } else {
01145      Q.m[2][0] = Q.m[0][1]*Q.m[1][2] - Q.m[0][2]*Q.m[1][1] ;  /* cross */
01146      Q.m[2][1] = Q.m[0][2]*Q.m[1][0] - Q.m[0][0]*Q.m[1][2] ;  /* product */
01147      Q.m[2][2] = Q.m[0][0]*Q.m[1][1] - Q.m[0][1]*Q.m[1][0] ;
01148    }
01149 
01150    P = mat33_polar(Q) ;  /* P is orthog matrix closest to Q */
01151 
01152    R.m[0][0] = P.m[0][0] ; R.m[0][1] = P.m[0][1] ; R.m[0][2] = P.m[0][2] ;
01153    R.m[1][0] = P.m[1][0] ; R.m[1][1] = P.m[1][1] ; R.m[1][2] = P.m[1][2] ;
01154    R.m[2][0] = P.m[2][0] ; R.m[2][1] = P.m[2][1] ; R.m[2][2] = P.m[2][2] ;
01155 
01156    R.m[0][3] = R.m[1][3] = R.m[2][3] = 0.0 ; return R ;
01157 }
01158 
01159 /*---------------------------------------------------------------------------*/
01160 
01161 mat33 mat33_inverse( mat33 R )   /* inverse of 3x3 matrix */
01162 {
01163    double r11,r12,r13,r21,r22,r23,r31,r32,r33 , deti ;
01164    mat33 Q ;
01165                                                        /** INPUT MATRIX: **/
01166    r11 = R.m[0][0]; r12 = R.m[0][1]; r13 = R.m[0][2];  /* [ r11 r12 r13 ] */
01167    r21 = R.m[1][0]; r22 = R.m[1][1]; r23 = R.m[1][2];  /* [ r21 r22 r23 ] */
01168    r31 = R.m[2][0]; r32 = R.m[2][1]; r33 = R.m[2][2];  /* [ r31 r32 r33 ] */
01169 
01170    deti = r11*r22*r33-r11*r32*r23-r21*r12*r33
01171          +r21*r32*r13+r31*r12*r23-r31*r22*r13 ;
01172 
01173    if( deti != 0.0l ) deti = 1.0l / deti ;
01174 
01175    Q.m[0][0] = deti*( r22*r33-r32*r23) ;
01176    Q.m[0][1] = deti*(-r12*r33+r32*r13) ;
01177    Q.m[0][2] = deti*( r12*r23-r22*r13) ;
01178 
01179    Q.m[1][0] = deti*(-r21*r33+r31*r23) ;
01180    Q.m[1][1] = deti*( r11*r33-r31*r13) ;
01181    Q.m[1][2] = deti*(-r11*r23+r21*r13) ;
01182 
01183    Q.m[2][0] = deti*( r21*r32-r31*r22) ;
01184    Q.m[2][1] = deti*(-r11*r32+r31*r12) ;
01185    Q.m[2][2] = deti*( r11*r22-r21*r12) ;
01186 
01187    return Q ;
01188 }
01189 
01190 /*---------------------------------------------------------------------------*/
01191 
01192 float mat33_determ( mat33 R )   /* determinant of 3x3 matrix */
01193 {
01194    double r11,r12,r13,r21,r22,r23,r31,r32,r33 ;
01195                                                        /** INPUT MATRIX: **/
01196    r11 = R.m[0][0]; r12 = R.m[0][1]; r13 = R.m[0][2];  /* [ r11 r12 r13 ] */
01197    r21 = R.m[1][0]; r22 = R.m[1][1]; r23 = R.m[1][2];  /* [ r21 r22 r23 ] */
01198    r31 = R.m[2][0]; r32 = R.m[2][1]; r33 = R.m[2][2];  /* [ r31 r32 r33 ] */
01199 
01200    return r11*r22*r33-r11*r32*r23-r21*r12*r33
01201          +r21*r32*r13+r31*r12*r23-r31*r22*r13 ;
01202 }
01203 
01204 /*---------------------------------------------------------------------------*/
01205 
01206 float mat33_rownorm( mat33 A )  /* max row norm of 3x3 matrix */
01207 {
01208    float r1,r2,r3 ;
01209 
01210    r1 = fabs(A.m[0][0])+fabs(A.m[0][1])+fabs(A.m[0][2]) ;
01211    r2 = fabs(A.m[1][0])+fabs(A.m[1][1])+fabs(A.m[1][2]) ;
01212    r3 = fabs(A.m[2][0])+fabs(A.m[2][1])+fabs(A.m[2][2]) ;
01213    if( r1 < r2 ) r1 = r2 ;
01214    if( r1 < r3 ) r1 = r3 ;
01215    return r1 ;
01216 }
01217 
01218 /*---------------------------------------------------------------------------*/
01219 
01220 float mat33_colnorm( mat33 A )  /* max column norm of 3x3 matrix */
01221 {
01222    float r1,r2,r3 ;
01223 
01224    r1 = fabs(A.m[0][0])+fabs(A.m[1][0])+fabs(A.m[2][0]) ;
01225    r2 = fabs(A.m[0][1])+fabs(A.m[1][1])+fabs(A.m[2][1]) ;
01226    r3 = fabs(A.m[0][2])+fabs(A.m[1][2])+fabs(A.m[2][2]) ;
01227    if( r1 < r2 ) r1 = r2 ;
01228    if( r1 < r3 ) r1 = r3 ;
01229    return r1 ;
01230 }
01231 
01232 /*---------------------------------------------------------------------------*/
01233 
01234 mat33 mat33_mul( mat33 A , mat33 B )  /* multiply 2 3x3 matrices */
01235 {
01236    mat33 C ; int i,j ;
01237    for( i=0 ; i < 3 ; i++ )
01238     for( j=0 ; j < 3 ; j++ )
01239       C.m[i][j] =  A.m[i][0] * B.m[0][j]
01240                  + A.m[i][1] * B.m[1][j]
01241                  + A.m[i][2] * B.m[2][j] ;
01242    return C ;
01243 }
01244 
01245 /*---------------------------------------------------------------------------*/
01246 /* Polar decomposition of a 3x3 matrix: finds the closest orthogonal matrix
01247    to input A (in both the Frobenius and L2 norms).  Algorithm is that from
01248    NJ Higham, SIAM J Sci Stat Comput, 7:1160-1174.
01249 -----------------------------------------------------------------------------*/
01250 
01251 mat33 mat33_polar( mat33 A )
01252 {
01253    mat33 X , Y , Z ;
01254    float alp,bet,gam,gmi , dif=1.0 ;
01255    int k=0 ;
01256 
01257    X = A ;
01258 
01259    /* force matrix to be nonsingular */
01260 
01261    gam = mat33_determ(X) ;
01262    while( gam == 0.0 ){        /* perturb matrix */
01263      gam = 0.00001 * ( 0.001 + mat33_rownorm(X) ) ;
01264      X.m[0][0] += gam ; X.m[1][1] += gam ; X.m[2][2] += gam ;
01265      gam = mat33_determ(X) ;
01266    }
01267 
01268    while(1){
01269      Y = mat33_inverse(X) ;
01270      if( dif > 0.3 ){     /* far from convergence */
01271        alp = sqrt( mat33_rownorm(X) * mat33_colnorm(X) ) ;
01272        bet = sqrt( mat33_rownorm(Y) * mat33_colnorm(Y) ) ;
01273        gam = sqrt( bet / alp ) ;
01274        gmi = 1.0 / gam ;
01275      } else {
01276        gam = gmi = 1.0 ;  /* close to convergence */
01277      }
01278      Z.m[0][0] = 0.5 * ( gam*X.m[0][0] + gmi*Y.m[0][0] ) ;
01279      Z.m[0][1] = 0.5 * ( gam*X.m[0][1] + gmi*Y.m[1][0] ) ;
01280      Z.m[0][2] = 0.5 * ( gam*X.m[0][2] + gmi*Y.m[2][0] ) ;
01281      Z.m[1][0] = 0.5 * ( gam*X.m[1][0] + gmi*Y.m[0][1] ) ;
01282      Z.m[1][1] = 0.5 * ( gam*X.m[1][1] + gmi*Y.m[1][1] ) ;
01283      Z.m[1][2] = 0.5 * ( gam*X.m[1][2] + gmi*Y.m[2][1] ) ;
01284      Z.m[2][0] = 0.5 * ( gam*X.m[2][0] + gmi*Y.m[0][2] ) ;
01285      Z.m[2][1] = 0.5 * ( gam*X.m[2][1] + gmi*Y.m[1][2] ) ;
01286      Z.m[2][2] = 0.5 * ( gam*X.m[2][2] + gmi*Y.m[2][2] ) ;
01287 
01288      dif = fabs(Z.m[0][0]-X.m[0][0])+fabs(Z.m[0][1]-X.m[0][1])
01289           +fabs(Z.m[0][2]-X.m[0][2])+fabs(Z.m[1][0]-X.m[1][0])
01290           +fabs(Z.m[1][1]-X.m[1][1])+fabs(Z.m[1][2]-X.m[1][2])
01291           +fabs(Z.m[2][0]-X.m[2][0])+fabs(Z.m[2][1]-X.m[2][1])
01292           +fabs(Z.m[2][2]-X.m[2][2])                          ;
01293 
01294      k = k+1 ;
01295      if( k > 100 || dif < 3.e-6 ) break ;  /* convergence or exhaustion */
01296      X = Z ;
01297    }
01298 
01299    return Z ;
01300 }
01301 
01302 /*---------------------------------------------------------------------------*/
01303 /* Input:  4x4 matrix that transforms (i,j,k) indexes to (x,y,z) coordinates,
01304            where +x=Right, +y=Anterior, +z=Superior.
01305            (Only the upper-left 3x3 corner of R is used herein.)
01306    Output: 3 orientation codes that correspond to the closest "standard"
01307            anatomical orientation of the (i,j,k) axes.
01308    Method: Find which permutation of (x,y,z) has the smallest angle to the
01309            (i,j,k) axes directions, which are the columns of the R matrix.
01310    Errors: The codes returned will be zero.
01311 
01312    For example, an axial volume might get return values of
01313      *icod = NIFTI_R2L   (i axis is mostly Right to Left)
01314      *jcod = NIFTI_P2A   (j axis is mostly Posterior to Anterior)
01315      *kcod = NIFTI_I2S   (k axis is mostly Inferior to Superior)
01316 -----------------------------------------------------------------------------*/
01317 
01318 void mat44_to_orientation( mat44 R , int *icod, int *jcod, int *kcod )
01319 {
01320    float xi,xj,xk , yi,yj,yk , zi,zj,zk , val,detQ,detP ;
01321    mat33 P , Q , M ;
01322    int i,j,k=0,p,q,r , ibest,jbest,kbest,pbest,qbest,rbest ;
01323    float vbest ;
01324 
01325    if( icod == NULL || jcod == NULL || kcod == NULL ) return ; /* bad */
01326 
01327    *icod = *jcod = *kcod = 0 ; /* error returns, if sh*t happens */
01328 
01329    /* load column vectors for each (i,j,k) direction from matrix */
01330 
01331    /*-- i axis --*/ /*-- j axis --*/ /*-- k axis --*/
01332 
01333    xi = R.m[0][0] ; xj = R.m[0][1] ; xk = R.m[0][2] ;
01334    yi = R.m[1][0] ; yj = R.m[1][1] ; yk = R.m[1][2] ;
01335    zi = R.m[2][0] ; zj = R.m[2][1] ; zk = R.m[2][2] ;
01336 
01337    /* normalize column vectors to get unit vectors along each ijk-axis */
01338 
01339    /* normalize i axis */
01340 
01341    val = sqrt( xi*xi + yi*yi + zi*zi ) ;
01342    if( val == 0.0 ) return ;                 /* stupid input */
01343    xi /= val ; yi /= val ; zi /= val ;
01344 
01345    /* normalize j axis */
01346 
01347    val = sqrt( xj*xj + yj*yj + zj*zj ) ;
01348    if( val == 0.0 ) return ;                 /* stupid input */
01349    xj /= val ; yj /= val ; zj /= val ;
01350 
01351    /* orthogonalize j axis to i axis, if needed */
01352 
01353    val = xi*xj + yi*yj + zi*zj ;    /* dot product between i and j */
01354    if( fabs(val) > 1.e-4 ){
01355      xj -= val*xi ; yj -= val*yi ; zj -= val*zi ;
01356      val = sqrt( xj*xj + yj*yj + zj*zj ) ;  /* must renormalize */
01357      if( val == 0.0 ) return ;              /* j was parallel to i? */
01358      xj /= val ; yj /= val ; zj /= val ;
01359    }
01360 
01361    /* normalize k axis; if it is zero, make it the cross product i x j */
01362 
01363    val = sqrt( xk*xk + yk*yk + zk*zk ) ;
01364    if( val == 0.0 ){ xk = yi*zj-zi*yj; yk = zi*xj-zj*xi ; zk=xi*yj-yi*xj ; }
01365    else            { xk /= val ; yk /= val ; zk /= val ; }
01366 
01367    /* orthogonalize k to i */
01368 
01369    val = xi*xk + yi*yk + zi*zk ;    /* dot product between i and k */
01370    if( fabs(val) > 1.e-4 ){
01371      xk -= val*xi ; yk -= val*yi ; zk -= val*zi ;
01372      val = sqrt( xk*xk + yk*yk + zk*zk ) ;
01373      if( val == 0.0 ) return ;      /* bad */
01374      xk /= val ; yk /= val ; zk /= val ;
01375    }
01376 
01377    /* orthogonalize k to j */
01378 
01379    val = xj*xk + yj*yk + zj*zk ;    /* dot product between j and k */
01380    if( fabs(val) > 1.e-4 ){
01381      xk -= val*xj ; yk -= val*yj ; zk -= val*zj ;
01382      val = sqrt( xk*xk + yk*yk + zk*zk ) ;
01383      if( val == 0.0 ) return ;      /* bad */
01384      xk /= val ; yk /= val ; zk /= val ;
01385    }
01386 
01387    Q.m[0][0] = xi ; Q.m[0][1] = xj ; Q.m[0][2] = xk ;
01388    Q.m[1][0] = yi ; Q.m[1][1] = yj ; Q.m[1][2] = yk ;
01389    Q.m[2][0] = zi ; Q.m[2][1] = zj ; Q.m[2][2] = zk ;
01390 
01391    /* at this point, Q is the rotation matrix from the (i,j,k) to (x,y,z) axes */
01392 
01393    detQ = mat33_determ( Q ) ;
01394    if( detQ == 0.0 ) return ; /* shouldn't happen unless user is a DUFIS */
01395 
01396    /* Build and test all possible +1/-1 coordinate permutation matrices P;
01397       then find the P such that the rotation matrix M=PQ is closest to the
01398       identity, in the sense of M having the smallest total rotation angle. */
01399 
01400    /* Despite the formidable looking 6 nested loops, there are
01401       only 3*3*3*2*2*2 = 216 passes, which will run very quickly. */
01402 
01403    vbest = -666.0 ; ibest=pbest=qbest=rbest=1 ; jbest=2 ; kbest=3 ;
01404    for( i=1 ; i <= 3 ; i++ ){     /* i = column number to use for row #1 */
01405     for( j=1 ; j <= 3 ; j++ ){    /* j = column number to use for row #2 */
01406      if( i == j ) continue ;
01407       for( k=1 ; k <= 3 ; k++ ){  /* k = column number to use for row #3 */
01408        if( i == k || j == k ) continue ;
01409        P.m[0][0] = P.m[0][1] = P.m[0][2] =
01410         P.m[1][0] = P.m[1][1] = P.m[1][2] =
01411          P.m[2][0] = P.m[2][1] = P.m[2][2] = 0.0 ;
01412        for( p=-1 ; p <= 1 ; p+=2 ){    /* p,q,r are -1 or +1      */
01413         for( q=-1 ; q <= 1 ; q+=2 ){   /* and go into rows #1,2,3 */
01414          for( r=-1 ; r <= 1 ; r+=2 ){
01415            P.m[0][i-1] = p ; P.m[1][j-1] = q ; P.m[2][k-1] = r ;
01416            detP = mat33_determ(P) ;             /* sign of permutation */
01417            if( detP * detQ <= 0.0 ) continue ;  /* doesn't match sign of Q */
01418            M = mat33_mul(P,Q) ;
01419 
01420            /* angle of M rotation = 2.0*acos(0.5*sqrt(1.0+trace(M)))       */
01421            /* we want largest trace(M) == smallest angle == M nearest to I */
01422 
01423            val = M.m[0][0] + M.m[1][1] + M.m[2][2] ; /* trace */
01424            if( val > vbest ){
01425              vbest = val ;
01426              ibest = i ; jbest = j ; kbest = k ;
01427              pbest = p ; qbest = q ; rbest = r ;
01428            }
01429    }}}}}}
01430 
01431    /* At this point ibest is 1 or 2 or 3; pbest is -1 or +1; etc.
01432 
01433       The matrix P that corresponds is the best permutation approximation
01434       to Q-inverse; that is, P (approximately) takes (x,y,z) coordinates
01435       to the (i,j,k) axes.
01436 
01437       For example, the first row of P (which contains pbest in column ibest)
01438       determines the way the i axis points relative to the anatomical
01439       (x,y,z) axes.  If ibest is 2, then the i axis is along the y axis,
01440       which is direction P2A (if pbest > 0) or A2P (if pbest < 0).
01441 
01442       So, using ibest and pbest, we can assign the output code for
01443       the i axis.  Mutatis mutandis for the j and k axes, of course. */
01444 
01445    switch( ibest*pbest ){
01446      case  1: i = NIFTI_L2R ; break ;
01447      case -1: i = NIFTI_R2L ; break ;
01448      case  2: i = NIFTI_P2A ; break ;
01449      case -2: i = NIFTI_A2P ; break ;
01450      case  3: i = NIFTI_I2S ; break ;
01451      case -3: i = NIFTI_S2I ; break ;
01452    }
01453 
01454    switch( jbest*qbest ){
01455      case  1: j = NIFTI_L2R ; break ;
01456      case -1: j = NIFTI_R2L ; break ;
01457      case  2: j = NIFTI_P2A ; break ;
01458      case -2: j = NIFTI_A2P ; break ;
01459      case  3: j = NIFTI_I2S ; break ;
01460      case -3: j = NIFTI_S2I ; break ;
01461    }
01462 
01463    switch( kbest*rbest ){
01464      case  1: k = NIFTI_L2R ; break ;
01465      case -1: k = NIFTI_R2L ; break ;
01466      case  2: k = NIFTI_P2A ; break ;
01467      case -2: k = NIFTI_A2P ; break ;
01468      case  3: k = NIFTI_I2S ; break ;
01469      case -3: k = NIFTI_S2I ; break ;
01470    }
01471 
01472    *icod = i ; *jcod = j ; *kcod = k ; return ;
01473 }
01474 
01475 /*---------------------------------------------------------------------------*/
01476 /* Routines to swap byte arrays in various ways:
01477     -  2 at a time:  ab               -> ba               [short]
01478     -  4 at a time:  abcd             -> dcba             [int, float]
01479     -  8 at a time:  abcdDCBA         -> ABCDdcba         [long long, double]
01480     - 16 at a time:  abcdefghHGFEDCBA -> ABCDEFGHhgfedcba [long double]
01481 -----------------------------------------------------------------------------*/
01482 
01483 typedef struct { unsigned char a,b ; } twobytes ;
01484 
01485 void swap_2bytes( int n , void *ar )    /* 2 bytes at a time */
01486 {
01487    register int ii ;
01488    register twobytes *tb = (twobytes *)ar ;
01489    register unsigned char tt ;
01490 
01491    for( ii=0 ; ii < n ; ii++ ){
01492      tt = tb[ii].a ; tb[ii].a = tb[ii].b ; tb[ii].b = tt ;
01493    }
01494    return ;
01495 }
01496 
01497 /*---------------------------------------------------------------------------*/
01498 
01499 typedef struct { unsigned char a,b,c,d ; } fourbytes ;
01500 
01501 void swap_4bytes( int n , void *ar )    /* 4 bytes at a time */
01502 {
01503    register int ii ;
01504    register fourbytes *tb = (fourbytes *)ar ;
01505    register unsigned char tt ;
01506 
01507    for( ii=0 ; ii < n ; ii++ ){
01508      tt = tb[ii].a ; tb[ii].a = tb[ii].d ; tb[ii].d = tt ;
01509      tt = tb[ii].b ; tb[ii].b = tb[ii].c ; tb[ii].c = tt ;
01510    }
01511    return ;
01512 }
01513 
01514 /*---------------------------------------------------------------------------*/
01515 
01516 typedef struct { unsigned char a,b,c,d , D,C,B,A ; } eightbytes ;
01517 
01518 void swap_8bytes( int n , void *ar )    /* 8 bytes at a time */
01519 {
01520    register int ii ;
01521    register eightbytes *tb = (eightbytes *)ar ;
01522    register unsigned char tt ;
01523 
01524    for( ii=0 ; ii < n ; ii++ ){
01525      tt = tb[ii].a ; tb[ii].a = tb[ii].A ; tb[ii].A = tt ;
01526      tt = tb[ii].b ; tb[ii].b = tb[ii].B ; tb[ii].B = tt ;
01527      tt = tb[ii].c ; tb[ii].c = tb[ii].C ; tb[ii].C = tt ;
01528      tt = tb[ii].d ; tb[ii].d = tb[ii].D ; tb[ii].D = tt ;
01529    }
01530    return ;
01531 }
01532 
01533 /*---------------------------------------------------------------------------*/
01534 
01535 typedef struct { unsigned char a,b,c,d,e,f,g,h ,
01536                                H,G,F,E,D,C,B,A  ; } sixteenbytes ;
01537 
01538 void swap_16bytes( int n , void *ar )    /* 16 bytes at a time */
01539 {
01540    register int ii ;
01541    register sixteenbytes *tb = (sixteenbytes *)ar ;
01542    register unsigned char tt ;
01543 
01544    for( ii=0 ; ii < n ; ii++ ){
01545      tt = tb[ii].a ; tb[ii].a = tb[ii].A ; tb[ii].A = tt ;
01546      tt = tb[ii].b ; tb[ii].b = tb[ii].B ; tb[ii].B = tt ;
01547      tt = tb[ii].c ; tb[ii].c = tb[ii].C ; tb[ii].C = tt ;
01548      tt = tb[ii].d ; tb[ii].d = tb[ii].D ; tb[ii].D = tt ;
01549 
01550      tt = tb[ii].e ; tb[ii].e = tb[ii].E ; tb[ii].E = tt ;
01551      tt = tb[ii].f ; tb[ii].f = tb[ii].F ; tb[ii].F = tt ;
01552      tt = tb[ii].g ; tb[ii].g = tb[ii].G ; tb[ii].G = tt ;
01553      tt = tb[ii].h ; tb[ii].h = tb[ii].H ; tb[ii].H = tt ;
01554    }
01555    return ;
01556 }
01557 
01558 /*---------------------------------------------------------------------------*/
01559 
01560 void swap_Nbytes( int n , int siz , void *ar )  /* subsuming case */
01561 {
01562    switch( siz ){
01563      case 2:  swap_2bytes ( n , ar ) ; break ;
01564      case 4:  swap_4bytes ( n , ar ) ; break ;
01565      case 8:  swap_8bytes ( n , ar ) ; break ;
01566      case 16: swap_16bytes( n , ar ) ; break ;
01567    }
01568    return ;
01569 }
01570 
01571 /*---------------------------------------------------------------*/
01572 /* Byte swap NIFTI-1 file header in various places and ways.
01573    If is_nifti is nonzero, will also swap the NIFTI-specific
01574    components of the header; otherwise, only the components
01575    common to NIFTI and ANALYZE will be swapped.
01576 ---------------------------------------------------------------- */
01577 
01578 void swap_nifti_header( struct nifti_1_header *h , int is_nifti )
01579 {
01580 
01581 #if 0                /* ANALYZE fields not used by this software */
01582    swap_4(h->sizeof_hdr) ;
01583    swap_4(h->extents) ;
01584    swap_2(h->session_error) ;
01585    swap_4(h->compressed) ;
01586    swap_4(h->glmax) ; swap_4(h->glmin) ;
01587 #endif
01588 
01589    /* this stuff is always present, for ANALYZE and NIFTI */
01590 
01591    swap_2bytes( 8 , h->dim ) ;
01592    swap_4bytes( 8 , h->pixdim ) ;
01593 
01594    swap_2(h->datatype) ;
01595    swap_2(h->bitpix) ;
01596 
01597    swap_4(h->vox_offset); swap_4(h->cal_max); swap_4(h->cal_min);
01598 
01599    /* this stuff is NIFTI specific */
01600 
01601    if( is_nifti ){
01602      swap_2(h->qform_code); swap_2(h->sform_code);
01603      swap_4(h->quatern_b); swap_4(h->quatern_c); swap_4(h->quatern_d);
01604      swap_4(h->qoffset_x); swap_4(h->qoffset_y); swap_4(h->qoffset_z);
01605      swap_4(h->intent_p1); swap_4(h->intent_p2); swap_4(h->intent_p3);
01606      swap_4(h->scl_slope); swap_4(h->scl_inter);
01607      swap_4bytes(4,h->srow_x);
01608      swap_4bytes(4,h->srow_y);
01609      swap_4bytes(4,h->srow_z);
01610      swap_2(h->intent_code); swap_4(h->toffset);
01611      swap_2(h->slice_start); swap_2(h->slice_end);
01612      swap_4(h->slice_duration);
01613    }
01614    return ;
01615 }
01616 
01617 /* rcr - start I/O routines here */
01618 
01619 #define USE_STAT
01620 #ifdef  USE_STAT
01621 /*---------------------------------------------------------------------------*/
01622 /* Return the file length (0 if file not found or has no contents).
01623    This is a Unix-specific function, since it uses stat().
01624 -----------------------------------------------------------------------------*/
01625 #include <sys/types.h>
01626 #include <sys/stat.h>
01627 
01628 unsigned int get_filesize( char *pathname )
01629 {
01630    struct stat buf ; int ii ;
01631 
01632    if( pathname == NULL || *pathname == '\0' ) return 0 ;
01633    ii = stat( pathname , &buf ); if( ii != 0 ) return 0 ;
01634    return (unsigned int)buf.st_size ;
01635 }
01636 
01637 #else  /*---------- non-Unix version of the above, less efficient -----------*/
01638 
01639 unsigned int get_filesize( char *pathname )
01640 {
01641    znzFile fp ; unsigned int len ;
01642 
01643    if( pathname == NULL || *pathname == '\0' ) return 0 ;
01644    fp = znzopen(pathname,"rb",0); if( znz_isnull(fp) ) return 0 ;
01645    znzseek(fp,0L,SEEK_END) ; len = (unsigned int)znztell(fp) ;
01646    znzclose(fp) ; return len ;
01647 }
01648 
01649 #endif /* USE_STAT */
01650 
01651 
01652 size_t nifti_get_volsize(nifti_image *nim)
01653 {
01654    return (size_t)(nim->nbyper) * (size_t)(nim->nvox) ; /* total bytes */
01655 }
01656 
01657 
01658 /*--------------------------------------------------------------------------*/
01659 /* Support functions for filenames in read and write - allows for gzipped
01660    files
01661 */
01662 
01663 
01664 int nifti_fileexists(char* fname)
01665 {
01666    znzFile fp;
01667    fp = znzopen( fname , "rb" , 1 ) ;
01668    if( !znz_isnull(fp) )  { znzclose(fp);  return 1; }
01669    return 0;
01670 }
01671 
01672 int nifti_validfilename(char* fname)
01673 {
01674    char * ext;
01675    int                         len;
01676 
01677    /** check input file(s) for sanity **/
01678    if( fname == NULL || *fname == '\0' ) return 0;
01679 
01680    len = strlen(fname);
01681 
01682    if( len < 1 ) {
01683       if ( gni_debug > 0 )
01684          fprintf(stderr,"-- empty filename in nifti_validfilename()\n");
01685       return 0;
01686    }
01687 
01688    ext = nifti_find_file_extension((char *)fname);
01689 
01690    if ( ext && ext == fname ) {   /* then no filename prefix */
01691       if ( gni_debug > 0 )
01692          fprintf(stderr,"-- no prefix for filename '%s'\n", fname);
01693       return 0;
01694    }
01695 
01696    return 1;
01697 }
01698 
01699 char * nifti_find_file_extension( char * name )
01700 {
01701    char * ext;
01702    int    len;
01703 
01704    if ( ! name ) return NULL;
01705 
01706    len = strlen(name);
01707    if ( len < 4 ) return NULL;
01708 
01709    ext = name + len - 4;
01710 
01711    if ( (strcmp(ext, ".hdr") == 0) || (strcmp(ext, ".img") == 0) ||
01712         (strcmp(ext, ".nia") == 0) || (strcmp(ext, ".nii") == 0) )
01713       return ext;
01714 
01715 #ifdef HAVE_ZLIB
01716    if ( len < 7 ) return NULL;
01717 
01718    ext = name - 7;
01719    if ( (strcmp(ext, ".hdr.gz") == 0) || (strcmp(ext, ".img.gz") == 0) ||
01720         (strcmp(ext, ".nia.gz") == 0) || (strcmp(ext, ".nii.gz") == 0) )
01721       return ext;
01722 #endif
01723 
01724    return NULL;
01725 }
01726 
01727 static int nifti_is_gzfile(char* fname)
01728 {
01729   /* return true if the filename ends with .gz */
01730   if (fname == NULL) { return 0; }
01731 #ifdef HAVE_ZLIB
01732   if (strcmp(fname + strlen(fname) - 3,".gz")==0) { return 1; }
01733 #endif
01734   return 0;
01735 }
01736 
01737 
01738 char * nifti_makebasename(char* fname)
01739 {
01740    /*
01741       NB: it allocates memory for basename which should be freed
01742         when no longer required
01743    */
01744    char *basename, *ext;
01745 
01746    basename=nifti_strdup(fname);
01747 
01748    ext = nifti_find_file_extension(basename);
01749    if ( ext ) *ext = '\0';  /* clear out extension */
01750    
01751    return basename;  /* in either case */
01752 }
01753 
01754 void nifti_set_debug_level( int level )
01755 {
01756     gni_debug = level;
01757 }
01758 
01759 
01760 /*----------------------------------------------------------------------
01761  * returns filename of header on success and NULL if no appropriate file
01762  *   could be found 
01763  * NB: it allocates memory for hdrname which should be freed
01764  *   when no longer required
01765  ----------------------------------------------------------------------*/
01766 static char * nifti_findhdrname(char* fname)
01767 {
01768    char *basename, *hdrname, *ext;
01769    char  elist[2][5] = { ".hdr", ".nii" };
01770    int   efirst;
01771 
01772    /** check input file(s) for sanity **/
01773    if( !nifti_validfilename(fname) ) return NULL;
01774 
01775    basename =  nifti_makebasename(fname);
01776    if( !basename ) return NULL;   /* only on string alloc failure */
01777 
01778    /* return filename if it has a valid extension and exists
01779       (except if it is an .img file (and maybe .gz)) */
01780    ext = nifti_find_file_extension(fname);
01781    if ( ext && nifti_fileexists(fname) ) { 
01782      if ( strncmp(ext,".img",4) != 0 ){
01783         hdrname = nifti_strdup(fname); 
01784         return hdrname; 
01785      }
01786    }
01787 
01788    /* So the requested name is a basename, contains .img, or does not exist. */
01789    /* In any case, use basename. */
01790 
01791    /* if .img, look for .hdr, .hdr.gz, .nii, .nii.gz, in that order */
01792    /* else,    look for .nii, .nii.gz, .hdr, .hdr.gz, in that order */
01793 
01794    /* if we get more extension choices, this could be a loop */
01795 
01796    if ( ext && strncmp(ext,".img",4) != 0 ) efirst = 0;
01797    else                                     efirst = 1;
01798 
01799    hdrname = (char *)calloc(sizeof(char),strlen(basename)+8);
01800 
01801    strcpy(hdrname,basename);
01802    strcat(hdrname,elist[efirst]);
01803    if (nifti_fileexists(hdrname)) { free(basename); return hdrname; }
01804 #ifdef HAVE_ZLIB
01805    strcat(hdrname,".gz"); 
01806    if (nifti_fileexists(hdrname)) { free(basename); return hdrname; }
01807 #endif
01808 
01809    /* okay, try the other possibility */
01810 
01811    efirst = 1 - efirst;
01812 
01813    strcpy(hdrname,basename);
01814    strcat(hdrname,elist[efirst]);
01815    if (nifti_fileexists(hdrname)) { free(basename); return hdrname; }
01816 #ifdef HAVE_ZLIB
01817    strcat(hdrname,".gz"); 
01818    if (nifti_fileexists(hdrname)) { free(basename); return hdrname; }
01819 #endif
01820 
01821    /** if it gets to here then nothing has been found -> failure! **/
01822    free(basename); 
01823    free(hdrname); 
01824    return NULL;
01825 }
01826 
01827 
01828 /*----------------------------------------------------------------------
01829  * returns filename of data/img file on success and NULL if no appropriate
01830  * file could be found
01831  * NB: it allocates memory for imgname which should be freed
01832  *   when no longer required
01833  ----------------------------------------------------------------------*/
01834 static char * nifti_findimgname(char* fname , int nifti_type)
01835 {
01836    char *basename, *imgname, ext[2][5] = { ".nii", ".img" };
01837    int  first;  /* first extension to use */
01838 
01839    /** check input file(s) for sanity **/
01840 
01841    if( !nifti_validfilename(fname) ) return NULL;
01842 
01843    /** use nifti_type to decide whether to look for .img or .nii **/
01844    /** if using compression libraries, .gz files are looked for first **/
01845    basename =  nifti_makebasename(fname);
01846    imgname = (char *)calloc(sizeof(char),strlen(basename)+8);
01847 
01848    /* test one form, then another (don't assume input type from image type) */
01849    /* if we get 3 or more extensions, can make a loop here...               */
01850 
01851    if (nifti_type == 1) first = 0;   /* type 1      should match .nii */
01852    else                 first = 1;   /* type 0 or 2 should match .img */
01853 
01854    strcpy(imgname,basename);
01855    strcat(imgname,ext[first]);
01856    if (nifti_fileexists(imgname)) { free(basename); return imgname; }
01857 #ifdef HAVE_ZLIB  /* then also check for .gz */
01858    strcat(imgname,".gz");
01859    if (nifti_fileexists(imgname)) { free(basename); return imgname; }
01860 #endif
01861 
01862    /* failed to find image file with expected extension, try the other */
01863 
01864    strcpy(imgname,basename);
01865    strcat(imgname,ext[1-first]);  /* can do this with only 2 choices */
01866    if (nifti_fileexists(imgname)) { free(basename); return imgname; }
01867 #ifdef HAVE_ZLIB  /* then also check for .gz */
01868    strcat(imgname,".gz");
01869    if (nifti_fileexists(imgname)) { free(basename); return imgname; }
01870 #endif
01871 
01872    /* otherwise - failure */
01873    free(basename); 
01874    free(imgname); 
01875    return NULL;
01876 }
01877    
01878 /*--------------------------------------------------------------------------*/
01879 /* Determine if this is a NIFTI-formatted file.
01880    - returns 0 if file looks like ANALYZE 7.5 [checks sizeof_hdr field == 348]
01881    - returns 1 if file marked as NIFTI (header+data in 1 file)
01882    - returns 2 if file marked as NIFTI (header+data in 2 files)
01883    - returns -1 if it can't tell, file doesn't exist, etc.
01884 ----------------------------------------------------------------------------*/
01885 
01886 int is_nifti_file( char *hname )
01887 {
01888    struct nifti_1_header nhdr ;
01889    znzFile fp ;
01890    int ii ;
01891    char *tmpname;
01892 
01893    /* bad input name? */
01894 
01895    if( !nifti_validfilename(hname) ) return -1 ;
01896 
01897    /* open file */
01898 
01899    tmpname = nifti_findhdrname(hname);
01900    if( tmpname == NULL ){
01901       if( gni_debug > 0 )
01902          fprintf(stderr,"** no header file found for '%s'\n",hname);
01903       return -1;
01904    }
01905    fp = znzopen( tmpname , "rb" , 1 ) ;
01906    free(tmpname);
01907    if (znz_isnull(fp))                      return -1 ;  /* bad open? */
01908 
01909    /* read header, close file */
01910 
01911    ii = znzread( &nhdr , 1 , sizeof(nhdr) , fp ) ;
01912    znzclose( fp ) ;
01913    if( ii < sizeof(nhdr) )               return -1 ;  /* bad read? */
01914 
01915    /* check for NIFTI-ness */
01916 
01917    if( NIFTI_VERSION(nhdr) != 0 ){
01918      return ( NIFTI_ONEFILE(nhdr) ) ? 1 : 2 ;
01919    }
01920 
01921    /* check for ANALYZE-ness (sizeof_hdr field == 348) */
01922 
01923    ii = nhdr.sizeof_hdr ;
01924    if( ii == sizeof(nhdr) ) return 0 ;  /* matches */
01925 
01926    /* try byte-swapping header */
01927 
01928    swap_4(ii) ;
01929    if( ii == sizeof(nhdr) ) return 0 ;  /* matches */
01930 
01931    return -1 ;                          /* not good */
01932 }
01933 
01934 int print_hex_vals( char * data, int nbytes, FILE * fp )
01935 {
01936    int c;
01937 
01938    if ( !data || nbytes < 1 || !fp ) return -1;
01939 
01940    fputs("0x", fp);
01941    for ( c = 0; c < nbytes; c++ )
01942       fprintf(fp, " %x", data[c]);
01943 
01944    return 0;
01945 }
01946 
01947 int disp_nifti_1_header( char * info, nifti_1_header * hp )
01948 {
01949    int c;
01950 
01951    fputs( "-------------------------------------------------------\n", stderr );
01952    if ( info )  fputs( info, stderr );
01953    if ( !hp  ){ fputs(" ** no nifti_1_header to display!\n",stderr); return 1; }
01954 
01955    fprintf(stderr," nifti_1_header :\n"
01956            "    sizeof_hdr     = %d\n"
01957            "    data_type[10]  = ", hp->sizeof_hdr);
01958    print_hex_vals(hp->data_type, 10, stderr);
01959    fprintf(stderr, "\n"
01960            "    db_name[18]    = ");
01961    print_hex_vals(hp->db_name, 18, stderr);
01962    fprintf(stderr, "\n"
01963            "    extents        = %d\n"
01964            "    session_error  = %d\n"
01965            "    regular        = 0x%x\n"
01966            "    dim_info       = 0x%x\n",
01967       hp->extents, hp->session_error, hp->regular, hp->dim_info );
01968    fprintf(stderr, "    dim[8]         =");
01969    for ( c = 0; c < 8; c++ ) fprintf(stderr," %d", hp->dim[c]);
01970    fprintf(stderr, "\n"
01971            "    intent_p1      = %f\n"
01972            "    intent_p2      = %f\n"
01973            "    intent_p3      = %f\n"
01974            "    intent_code    = %d\n"
01975            "    datatype       = %d\n"
01976            "    bitpix         = %d\n"
01977            "    slice_start    = %d\n"
01978            "    pixdim[8]      =",
01979            hp->intent_p1, hp->intent_p2, hp->intent_p3, hp->intent_code,
01980            hp->datatype, hp->bitpix, hp->slice_start);
01981    /* break pixdim over 2 lines */
01982    for ( c = 0; c < 4; c++ ) fprintf(stderr," %f", hp->pixdim[c]);
01983    fprintf(stderr, "\n                    ");
01984    for ( c = 4; c < 8; c++ ) fprintf(stderr," %f", hp->pixdim[c]);
01985    fprintf(stderr, "\n"
01986            "    vox_offset     = %f\n"
01987            "    scl_slope      = %f\n"
01988            "    scl_inter      = %f\n"
01989            "    slice_end      = %d\n"
01990            "    slice_code     = %d\n"
01991            "    xyzt_units     = 0x%x\n"
01992            "    cal_max        = %f\n"
01993            "    cal_min        = %f\n"
01994            "    slice_duration = %f\n"
01995            "    toffset        = %f\n"
01996            "    glmax          = %d\n"
01997            "    glmin          = %d\n",
01998            hp->vox_offset, hp->scl_slope, hp->scl_inter, hp->slice_end,
01999            hp->slice_code, hp->xyzt_units, hp->cal_max, hp->cal_min,
02000            hp->slice_duration, hp->toffset, hp->glmax, hp->glmin);
02001    fprintf(stderr,
02002            "    descrip        = '%s'\n"
02003            "    aux_file       = '%s'\n"
02004            "    qform_code     = %d\n"
02005            "    sform_code     = %d\n"
02006            "    quatern_b      = %f\n"
02007            "    quatern_c      = %f\n"
02008            "    quatern_d      = %f\n"
02009            "    qoffset_x      = %f\n"
02010            "    qoffset_y      = %f\n"
02011            "    qoffset_z      = %f\n"
02012            "    srow_x[4]      = %f, %f, %f, %f\n"
02013            "    srow_y[4]      = %f, %f, %f, %f\n"
02014            "    srow_z[4]      = %f, %f, %f, %f\n"
02015            "    intent_name    = %-16s\n"
02016            "    magic          = %-4s\n",
02017            hp->descrip, hp->aux_file, hp->qform_code, hp->sform_code,
02018            hp->quatern_b, hp->quatern_c, hp->quatern_d,
02019            hp->qoffset_x, hp->qoffset_y, hp->qoffset_z,
02020            hp->srow_x[0], hp->srow_x[1], hp->srow_x[2], hp->srow_x[3],
02021            hp->srow_y[0], hp->srow_y[1], hp->srow_y[2], hp->srow_y[3],
02022            hp->srow_z[0], hp->srow_z[1], hp->srow_z[2], hp->srow_z[3],
02023            hp->intent_name, hp->magic);
02024    fputs( "-------------------------------------------------------\n", stderr );
02025 
02026    return 0;
02027 }
02028 
02029 
02030 #undef  ERREX
02031 #define ERREX(msg)                                           \
02032  do{ fprintf(stderr,"** ERROR: nifti_convert_nhdr2nim: %s\n", (msg) ) ;  \
02033      return NULL ; } while(0)
02034 
02035 nifti_image* nifti_convert_nhdr2nim(struct nifti_1_header nhdr, char* fname)
02036 {
02037   int   ii , doswap , ioff, ndim, nvox ;
02038   int   is_nifti , is_onefile ;
02039   short ss ;
02040   char *iname=NULL;
02041   nifti_image *nim;
02042 
02043    nim = (nifti_image *) calloc( 1 , sizeof(nifti_image) ) ;
02044    if( !nim ) ERREX("failed to allocate nifti image");
02045 
02046    nim->fname=NULL;
02047    nim->iname=NULL;
02048 
02049   /** check if have to swap bytes **/
02050   
02051    doswap = 0 ;                                           /* swap data flag */
02052    ss = nhdr.dim[0] ;
02053    if( ss != 0 ){                            /* check dim[0] for good value */
02054      if( ss < 0 || ss > 7 ){
02055        swap_2(ss) ;
02056        if( ss < 0 || ss > 7 )            ERREX("bad dim[0]") ;
02057        doswap = 1 ;
02058      }
02059    } else {                       /* dim[0] == 0 is illegal, but does occur */
02060      ii = nhdr.sizeof_hdr ;            /* so check sizeof_hdr field instead */
02061 
02062      if( ii != sizeof(nhdr) ){
02063        swap_4(ii) ;
02064        if( ii != sizeof(nhdr) )          ERREX("bad sizeof_hdr") ;
02065        doswap = 1 ;
02066      }
02067    }
02068 
02069    /** determine if this is a NIFTI-1 compliant header **/
02070 
02071    is_nifti = NIFTI_VERSION(nhdr) ;
02072    if( doswap ) {
02073       if ( gni_debug > 2 ) disp_nifti_1_header("-d ni1 pre-swap: ", &nhdr);
02074       swap_nifti_header( &nhdr , is_nifti ) ;
02075    }
02076 
02077    if ( gni_debug > 1 ) disp_nifti_1_header("-d nhdr2nim : ", &nhdr);
02078 
02079    if( nhdr.datatype == DT_BINARY ||
02080        nhdr.datatype == DT_UNKNOWN  )    ERREX("bad datatype") ;
02081 
02082    if( nhdr.dim[1] <= 0 )                ERREX("bad dim[1]") ;
02083 
02084    for( ii=2 ; ii <= 7 ; ii++ )
02085      if( nhdr.dim[ii] <= 0 ) nhdr.dim[ii] = 1 ;  /* fix bad dim[] values */
02086 
02087    /** get number of dimensions (ignoring dim[0] now) **/
02088 
02089    for( ii=7 ; ii >= 2 ; ii-- )            /* loop backwards until we  */
02090      if( nhdr.dim[ii] > 1 ) break ;        /* find a dim bigger than 1 */
02091    ndim = ii ;
02092 
02093    /* set bad grid spacings to 1.0 */
02094 
02095    for( ii=1 ; ii <= 7 ; ii++ ){
02096      if( nhdr.pixdim[ii] == 0.0         ||
02097          !IS_GOOD_FLOAT(nhdr.pixdim[ii])  ) nhdr.pixdim[ii] = 1.0 ;
02098    }
02099 
02100   is_onefile = is_nifti && NIFTI_ONEFILE(nhdr) ;
02101 
02102   if( is_nifti ) nim->nifti_type = (is_onefile) ? 1 : 2 ;
02103   else           nim->nifti_type = 0 ;
02104   
02105   ii = short_order() ;
02106   if( doswap )   nim->byteorder = REVERSE_ORDER(ii) ;
02107   else           nim->byteorder = ii ;
02108   
02109 
02110   /** dimensions of data array **/
02111   
02112   nim->ndim = nim->dim[0] = ndim ;
02113   nim->nx   = nim->dim[1] = nhdr.dim[1]; nvox  = nim->nx;
02114   nim->ny   = nim->dim[2] = nhdr.dim[2]; nvox *= nim->ny;
02115   nim->nz   = nim->dim[3] = nhdr.dim[3]; nvox *= nim->nz;
02116   nim->nt   = nim->dim[4] = nhdr.dim[4]; nvox *= nim->nt;
02117   nim->nu   = nim->dim[5] = nhdr.dim[5]; nvox *= nim->nu;
02118   nim->nv   = nim->dim[6] = nhdr.dim[6]; nvox *= nim->nv;
02119   nim->nw   = nim->dim[7] = nhdr.dim[7]; nvox *= nim->nw; nim->nvox = nvox;
02120   
02121   /** type of data in voxels and how many bytes per voxel */
02122   
02123   nim->datatype = nhdr.datatype ;
02124   
02125   nifti_datatype_sizes( nim->datatype , &(nim->nbyper) , &(nim->swapsize) ) ;
02126   if( nim->nbyper == 0 ){ free(nim); ERREX("bad datatype"); }
02127   
02128   /** grid spacings **/
02129   
02130   nim->dx = nim->pixdim[1] = nhdr.pixdim[1] ;
02131   nim->dy = nim->pixdim[2] = nhdr.pixdim[2] ;
02132   nim->dz = nim->pixdim[3] = nhdr.pixdim[3] ;
02133   nim->dt = nim->pixdim[4] = nhdr.pixdim[4] ;
02134   nim->du = nim->pixdim[5] = nhdr.pixdim[5] ;
02135   nim->dv = nim->pixdim[6] = nhdr.pixdim[6] ;
02136   nim->dw = nim->pixdim[7] = nhdr.pixdim[7] ;
02137   
02138   /** compute qto_xyz transformation from pixel indexes (i,j,k) to (x,y,z) **/
02139   
02140   if( !is_nifti || nhdr.qform_code <= 0 ){ /** default transformation **/
02141     
02142     nim->qto_xyz.m[0][0] = nim->dx ;  /* grid spacings */
02143     nim->qto_xyz.m[1][1] = nim->dy ;  /* along diagonal */
02144     nim->qto_xyz.m[2][2] = nim->dz ;
02145     
02146     /* off diagonal is zero */
02147     
02148     nim->qto_xyz.m[0][1]=nim->qto_xyz.m[0][2]=nim->qto_xyz.m[0][3] = 0.0;
02149     nim->qto_xyz.m[1][0]=nim->qto_xyz.m[1][2]=nim->qto_xyz.m[1][3] = 0.0;
02150     nim->qto_xyz.m[2][0]=nim->qto_xyz.m[2][1]=nim->qto_xyz.m[2][3] = 0.0;
02151     
02152     /* last row is always [ 0 0 0 1 ] */
02153     
02154     nim->qto_xyz.m[3][0]=nim->qto_xyz.m[3][1]=nim->qto_xyz.m[3][2] = 0.0;
02155     nim->qto_xyz.m[3][3]= 1.0 ;
02156     
02157     nim->qform_code = NIFTI_XFORM_UNKNOWN ;
02158     
02159   } else {                 /** NIFTI: quaternion-specified transformation **/
02160     
02161     nim->quatern_b = FIXED_FLOAT( nhdr.quatern_b ) ;
02162     nim->quatern_c = FIXED_FLOAT( nhdr.quatern_c ) ;
02163     nim->quatern_d = FIXED_FLOAT( nhdr.quatern_d ) ;
02164     
02165     nim->qoffset_x = FIXED_FLOAT(nhdr.qoffset_x) ;
02166     nim->qoffset_y = FIXED_FLOAT(nhdr.qoffset_y) ;
02167     nim->qoffset_z = FIXED_FLOAT(nhdr.qoffset_z) ;
02168     
02169     nim->qfac = (nhdr.pixdim[0] < 0.0) ? -1.0 : 1.0 ;  /* left-handedness? */
02170     
02171     nim->qto_xyz = quatern_to_mat44(
02172                       nim->quatern_b, nim->quatern_c, nim->quatern_d,
02173                       nim->qoffset_x, nim->qoffset_y, nim->qoffset_z,
02174                       nim->dx       , nim->dy       , nim->dz       ,
02175                       nim->qfac                                      ) ;
02176 
02177     nim->qform_code = nhdr.qform_code ;
02178 
02179     if( gni_debug > 1 )
02180        nifti_disp_matrix_orient("-d qform orientations:\n", nim->qto_xyz);
02181   }
02182   
02183   /** load inverse transformation (x,y,z) -> (i,j,k) **/
02184   
02185   nim->qto_ijk = mat44_inverse( nim->qto_xyz ) ;
02186   
02187   /** load sto_xyz affine transformation, if present **/
02188   
02189   if( !is_nifti || nhdr.sform_code <= 0 ){ /** no sto transformation **/
02190     
02191     nim->sform_code = NIFTI_XFORM_UNKNOWN ;
02192     
02193   } else {                            /** sto transformation from srow_*[] **/
02194     
02195     nim->sto_xyz.m[0][0] = nhdr.srow_x[0] ;
02196     nim->sto_xyz.m[0][1] = nhdr.srow_x[1] ;
02197     nim->sto_xyz.m[0][2] = nhdr.srow_x[2] ;
02198     nim->sto_xyz.m[0][3] = nhdr.srow_x[3] ;
02199     
02200     nim->sto_xyz.m[1][0] = nhdr.srow_y[0] ;
02201     nim->sto_xyz.m[1][1] = nhdr.srow_y[1] ;
02202     nim->sto_xyz.m[1][2] = nhdr.srow_y[2] ;
02203     nim->sto_xyz.m[1][3] = nhdr.srow_y[3] ;
02204     
02205     nim->sto_xyz.m[2][0] = nhdr.srow_z[0] ;
02206     nim->sto_xyz.m[2][1] = nhdr.srow_z[1] ;
02207     nim->sto_xyz.m[2][2] = nhdr.srow_z[2] ;
02208     nim->sto_xyz.m[2][3] = nhdr.srow_z[3] ;
02209     
02210     /* last row is always [ 0 0 0 1 ] */
02211     
02212     nim->sto_xyz.m[3][0]=nim->sto_xyz.m[3][1]=nim->sto_xyz.m[3][2] = 0.0;
02213     nim->sto_xyz.m[3][3]= 1.0 ;
02214     
02215     nim->sto_ijk = mat44_inverse( nim->sto_xyz ) ;
02216     
02217     nim->sform_code = nhdr.sform_code ;
02218 
02219     if( gni_debug > 1 )
02220        nifti_disp_matrix_orient("-d qform orientations:\n", nim->sto_xyz);
02221   }
02222   
02223   /* miscellaneous NIFTI stuff */
02224   
02225   if( is_nifti ){
02226     nim->scl_slope   = FIXED_FLOAT( nhdr.scl_slope ) ;
02227     nim->scl_inter   = FIXED_FLOAT( nhdr.scl_inter ) ;
02228     
02229     nim->intent_code = nhdr.intent_code ;
02230     
02231     nim->intent_p1 = FIXED_FLOAT( nhdr.intent_p1 ) ;
02232     nim->intent_p2 = FIXED_FLOAT( nhdr.intent_p2 ) ;
02233     nim->intent_p3 = FIXED_FLOAT( nhdr.intent_p3 ) ;
02234     
02235     nim->toffset   = FIXED_FLOAT( nhdr.toffset ) ;
02236     
02237     memcpy(nim->intent_name,nhdr.intent_name,15); nim->intent_name[15] = '\0';
02238     
02239     nim->xyz_units  = XYZT_TO_SPACE(nhdr.xyzt_units) ;
02240     nim->time_units = XYZT_TO_TIME (nhdr.xyzt_units) ;
02241     
02242     nim->freq_dim  = DIM_INFO_TO_FREQ_DIM ( nhdr.dim_info ) ;
02243     nim->phase_dim = DIM_INFO_TO_PHASE_DIM( nhdr.dim_info ) ;
02244     nim->slice_dim = DIM_INFO_TO_SLICE_DIM( nhdr.dim_info ) ;
02245     
02246     nim->slice_code     = nhdr.slice_code  ;
02247     nim->slice_start    = nhdr.slice_start ;
02248     nim->slice_end      = nhdr.slice_end   ;
02249     nim->slice_duration = FIXED_FLOAT(nhdr.slice_duration) ;
02250   }
02251   
02252   /* Miscellaneous ANALYZE stuff */
02253   
02254   nim->cal_min = FIXED_FLOAT(nhdr.cal_min) ;
02255   nim->cal_max = FIXED_FLOAT(nhdr.cal_max) ;
02256   
02257   memcpy(nim->descrip ,nhdr.descrip ,79) ; nim->descrip [79] = '\0' ;
02258   memcpy(nim->aux_file,nhdr.aux_file,23) ; nim->aux_file[23] = '\0' ;
02259   
02260    /** will read image data from file 'iname' starting at offset 'ioff' **/
02261 
02262    is_onefile = is_nifti && NIFTI_ONEFILE(nhdr) ;
02263 
02264    if( is_onefile ){
02265      ioff = (int)nhdr.vox_offset ;
02266      if( ioff < sizeof(nhdr) ) ioff = sizeof(nhdr) ;
02267    } else {
02268      ioff = (int)nhdr.vox_offset ;
02269    }
02270    nim->iname_offset = ioff ;
02271 
02272 
02273    /* deal with file names if set */
02274    if (fname!=NULL) {
02275      nim->fname = nifti_strdup(fname);
02276      /* determine name of image, if not already set */
02277      if (nim->iname==NULL) {
02278        if (is_onefile) {
02279          iname = nifti_strdup(nim->fname);
02280        } else {
02281          iname = nifti_findimgname(nim->fname,nim->nifti_type);
02282          if (iname==NULL)  ERREX("bad filename");
02283        }
02284        /* don't free iname, as now nim->iname is using this storage */
02285        nim->iname        = iname ;          /* save image filename */
02286      }
02287    } else { 
02288      nim->fname = NULL;  
02289      nim->iname = NULL; 
02290    }
02291 
02292    /* clear extension fields */
02293    nim->num_ext = 0;
02294    nim->ext_list = NULL;
02295 
02296    return nim;
02297 }
02298 
02299 
02300 /*--------------------------------------------------------------------------*/
02301 /* Read in a NIFTI-1 or ANALYZE-7.5 file (pair) into a nifti_image struct.
02302     - Input is .hdr or .nii filename.
02303     - Return value is NULL if something fails badly.
02304     - If read_data parameter is nonzero, the image data will actually
02305       be read in; otherwise, it will have to be read later
02306       (e.g., using the nifti_image_load() function).
02307     - The image data will be stored in whatever data format the
02308       input data is; no scaling will be applied.
02309     - DT_BINARY data is not supported!
02310     - nifti_image_free() can be used to delete the returned struct,
02311       when you are done with it.
02312 ----------------------------------------------------------------------------*/
02313 
02314 #undef  ERREX
02315 #define ERREX(msg)                                           \
02316  do{ fprintf(stderr,"** ERROR: nifti_image_open(%s): %s\n",  \
02317              (hname != NULL) ? hname : "(null)" , (msg) ) ;  \
02318      return fptr ; } while(0)
02319 
02320 static znzFile nifti_image_open( char *hname , char *opts , nifti_image **nim)
02321 {
02322   znzFile fptr=NULL;
02323   znz_setnull(fptr);
02324 
02325   /* open the hdr and reading it in, but do not load the data  */
02326   *nim = nifti_image_read(hname,0);
02327 
02328   /* open the image file, ready for reading
02329    * - NB: compressed works for all reads */
02330   if( ((*nim) == NULL)      || ((*nim)->iname == NULL) ||
02331       ((*nim)->nbyper <= 0) || ((*nim)->nvox <= 0)       ) ERREX("bad header info") ;
02332 
02333   /** open image data file **/  
02334   fptr = znzopen((*nim)->iname ,opts,1);
02335   if( znz_isnull(fptr) ) ERREX("Can't open data file") ;
02336   
02337   return fptr;
02338 }
02339 
02340 
02341 /* use macro LNI_FILE_ERROR instead of ERREX()
02342 #undef  ERREX
02343 #define ERREX(msg)                                           \
02344  do{ fprintf(stderr,"** ERROR: nifti_image_read(%s): %s\n",  \
02345              (hname != NULL) ? hname : "(null)" , (msg) ) ;  \
02346      return NULL ; } while(0)
02347 */
02348 
02349 nifti_image *nifti_image_read( char *hname , int read_data )
02350 {
02351    struct nifti_1_header  nhdr ;
02352    nifti_image           *nim ;
02353    znzFile                fp ;
02354    int                    ii , ilen;
02355    char                   fname[] = { "nifti_image_read" };
02356    char                   buf[16] , *workingname=NULL;
02357    
02358    /* determine file name to use for header */
02359    workingname = nifti_findhdrname(hname);
02360    if( workingname == NULL ){
02361       if( gni_debug > 0 )
02362          LNI_FERR(fname,"failed to find header file for", hname);
02363       return NULL;  /* check return */
02364    } else if( gni_debug > 1 )
02365       fprintf(stderr,"-d %s: found header filename '%s'\n",fname,workingname);
02366 
02367    fp = znzopen(workingname,"rb",1);
02368    if( znz_isnull(fp) ){
02369       if( gni_debug > 0 )
02370          LNI_FERR(fname,"failed to open header file",workingname);
02371       free(workingname);
02372       return NULL;
02373    }
02374 
02375    /** test if header file starts with ASCII string "<nifti_image";
02376        if so, read the dataset that special way and return now
02377        (this is NOT part of the NIFTI-1 standard!)                **/
02378 
02379    ii = znzread( buf , 1 , 12 , fp ) ;
02380    if( ii < 12 ){
02381       znzclose( fp ) ;
02382       if( gni_debug > 0 )
02383          LNI_FERR(fname,"short header read",workingname);
02384          free(workingname);
02385          return NULL;
02386    }
02387 
02388    znzrewind(fp) ;
02389    buf[12] = '\0' ;
02390    if( strcmp(buf,"<nifti_image") == 0 ){  /* have an ASCII header! */
02391      int slen, txt_size;
02392      char  *sbuf ;
02393      if( nifti_is_gzfile(workingname) ){
02394         LNI_FERR(fname, "compressed file with negative offset", workingname);
02395         free(workingname);
02396         return NULL;
02397      }
02398      slen = get_filesize( workingname ) ;
02399 
02400      if( gni_debug > 1 )
02401         fprintf(stderr,"-d %s: have ASCII image of size %d\n",fname,slen);
02402 
02403      if( slen > 65530 ) slen = 65530 ;
02404      sbuf = (char *)calloc(sizeof(char),slen+1) ;
02405      znzread( sbuf , 1 , slen , fp ) ;
02406      nim = nifti_image_from_ascii( sbuf, &txt_size ) ; free( sbuf ) ;
02407      if( nim == NULL ){
02408         LNI_FERR(fname,"failed nifti_image_from_ascii()",workingname);
02409         free(workingname);
02410         return NULL;
02411      }
02412      nim->nifti_type = 3 ;
02413 
02414      /* read extensions (but reposition file pointer, first */
02415      znzseek(fp, txt_size, SEEK_SET);
02416      (void) nifti_read_extensions(nim, fp);
02417 
02418      znzclose( fp ) ;
02419 
02420      nim->iname_offset = -1 ;  /* now check from the end of the file */
02421 
02422      if( read_data ) ii = nifti_image_load( nim ) ;
02423      else            nim->data = NULL ;
02424 
02425      free(workingname);
02426 
02427      /* check for nifti_image_load() failure, maybe bail out */
02428      if( read_data && ii != 0 ){
02429         if( gni_debug > 1 )
02430            fprintf(stderr,"-d failed image_load, free nifti image struct\n");
02431         free(nim);
02432         return NULL;
02433      }
02434 
02435      return nim ;
02436    }
02437 
02438    /**================ Normal case:  read binary header ===================*/
02439 
02440    ii = znzread( &nhdr , 1 , sizeof(nhdr) , fp ) ;       /* read the thing */
02441 
02442 /* rcr - test header struct for consistency here? */
02443 
02444    /* keep the file open for a while so we can check for extensions
02445     * after nifti_convert_nhdr2nim() */
02446 
02447    if( ii < sizeof(nhdr) ){
02448       if( gni_debug > 0 ){
02449          LNI_FERR(fname,"bad binary header read for file", workingname);
02450          fprintf(stderr,"  - read %d of %d bytes\n",ii, (int)sizeof(nhdr));
02451       }
02452       free(workingname);
02453       return NULL;
02454    }
02455 
02456    /*=== create output image struct and set it up ===*/
02457 
02458    /** convert all nhdr fields to nifti_image fields **/
02459    nim = nifti_convert_nhdr2nim(nhdr,workingname);
02460 
02461    if( nim == NULL ){
02462       znzclose( fp ) ;                                   /* close the file */
02463       if( gni_debug > 0 )
02464          LNI_FERR(fname,"failed to create nifti image from header",workingname);
02465       free(workingname); /* had to save this for debug message */
02466       return NULL;
02467    }
02468 
02469    if( gni_debug > 1 ){
02470       fprintf(stderr,"+d nifti_image_read(), have nifti image:\n");
02471       nifti_image_infodump(nim);
02472    }
02473 
02474    /* check for extensions, let us just ignore any errors here */
02475    (void) nifti_read_extensions(nim, fp);
02476 
02477    znzclose( fp ) ;                                      /* close the file */
02478    free(workingname);
02479    /* check that the data file is OK */
02480    if (!nifti_is_gzfile(nim->iname)) {
02481      /* can't use get_filesize on a compressed file   :( */
02482      ilen = get_filesize(nim->iname) ;
02483      if( ilen <= nim->iname_offset ){
02484         fprintf(stderr,"ERROR %s: file size less than offset (%d < %d)\n",
02485                 fname,ilen,nim->iname_offset);
02486         free(nim);
02487         return NULL;
02488      }
02489    }
02490 
02491    /** read the data if desired, then bug out **/
02492    if( read_data ) ii = nifti_image_load( nim ) ;
02493    else            nim->data = NULL ;
02494 
02495    return nim ;
02496 }
02497 
02498 
02499 /*----------------------------------------------------------------------
02500  * Read the extensions into the nifti_image struct   08 Dec 2004 [rickr]
02501  *
02502  * This function is called just after the header struct is read in, and
02503  * it is assumed the file pointer has not moved.
02504  *
02505  * return the number of extensions read in, or < 0 on error
02506  *----------------------------------------------------------------------*/
02507 static int nifti_read_extensions( nifti_image *nim, znzFile fp )
02508 {
02509    nifti1_extender    extdr;      /* defines extension existance  */
02510    nifti1_extension   extn;       /* single extension to process  */
02511    nifti1_extension * Elist;      /* list of processed extensions */
02512    int                posn, count;
02513    int                remaining;  /* until image data starts */
02514 
02515    if( !nim || znz_isnull(fp) ) {
02516       if( gni_debug > 0 )
02517          fprintf(stderr,"** nifti_read_extensions: bad inputs (%p,%p)\n",
02518                  nim, fp);
02519       return -1;
02520    }
02521 
02522    posn = znztell(fp);
02523  
02524    if( posn != sizeof(nifti_1_header) ){
02525       int dlevel_test = 0;
02526       if( nim->nifti_type == 3 ) dlevel_test = 1;
02527       if( gni_debug > dlevel_test )
02528          fprintf(stderr,"** WARNING: posn not header size (%d, %d)\n",
02529                  posn, (int)sizeof(nifti_1_header));
02530    }
02531 
02532    if( gni_debug > 2 )
02533       fprintf(stderr,"-d nre: posn = %d, offset = %d, type = %d\n",
02534               posn, nim->iname_offset, nim->nifti_type);
02535 
02536    if( nim->iname_offset > 0 &&
02537        (!nim->iname || (nim->fname && (strcmp(nim->fname,nim->iname) == 0))) )
02538    {
02539       /* then same file and offset exists, so compute remaining space */
02540       remaining = nim->iname_offset - posn - 4;    /* 4 for extender bytes */
02541       if( remaining <= 0 ){
02542          if( gni_debug > 2 )
02543             fprintf(stderr,"-d no space for extentions in file '%s'\n",
02544                     nim->fname);
02545          return 0;  /* no extensions to read */
02546       }
02547    }
02548    else           /* different files, so just read until we cannot */
02549      remaining = 0;
02550 
02551    count = znzread( extdr.extension, 1, 4, fp ); /* get extender */
02552 
02553    if( count < 4 ){
02554       if( gni_debug > 1 )
02555          fprintf(stderr,"-d no extender stored in header file '%s'\n",
02556                  nim->fname);
02557       return 0;
02558    }
02559 
02560    if( extdr.extension[0] != 1 ){
02561       if( gni_debug > 1 )
02562          fprintf(stderr,"-d extender[0] (%d) shows no extensions for '%s'\n",
02563                  extdr.extension[0], nim->fname);
02564       return 0;
02565    }
02566 
02567    /* so we expect extensions, but have no idea of how many there may be */
02568 
02569    count = 0;
02570    Elist = NULL;
02571    while ((remaining >= 0) && (nifti_read_next_extension(&extn, nim, fp) > 0))
02572    {
02573       if( nifti_add_exten_to_list(&extn, &Elist, count+1) < 0 ){
02574          if( gni_debug > 0 )
02575             fprintf(stderr,"** failed after %d successful extionsion reads\n",
02576                     count);
02577          return -1;
02578       }
02579 
02580       /* we have a new extension */
02581       if( gni_debug > 1 )
02582          fprintf(stderr,"+d found extension #%d, code = 0x%x, size = %d\n",
02583                  count, extn.ecode, extn.esize);
02584       if( remaining > 0 ) remaining -= extn.esize;
02585       count++;
02586    }
02587 
02588    if( gni_debug > 2 ) fprintf(stderr,"+d found %d extensions\n", count);
02589 
02590    nim->num_ext = count;
02591    nim->ext_list = Elist;
02592 
02593    return count;
02594 }
02595 
02596 
02597 /*----------------------------------------------------------------------
02598  * nifti_add_exten_to_list     - add new extension to the list
02599  *
02600  * We will append via malloc, copy and free, because on an error,
02601  * the old data pointers must all be released.
02602  *
02603  * return:
02604  *     0 on success
02605  *    -1 on error     (and free the entire list)
02606  *----------------------------------------------------------------------*/
02607 static int nifti_add_exten_to_list( nifti1_extension *  new_ext,
02608                                     nifti1_extension ** list, int new_length )
02609                                       
02610 {
02611    nifti1_extension * tmplist;
02612    int                count;
02613   
02614    tmplist = *list;
02615    *list = (nifti1_extension *)malloc(new_length * sizeof(nifti1_extension));
02616 
02617    /* check for failure first */
02618    if( ! *list ){
02619       fprintf(stderr,"** failed to alloc %d extension structs (%d bytes)\n",
02620               new_length, new_length*(int)sizeof(nifti1_extension));
02621       if( !tmplist ) return -1;  /* no old list to lose */
02622 
02623       for ( count = 0; count < new_length-1; count++ )
02624          if( tmplist[count].edata ) free(tmplist[count].edata);
02625       free(tmplist);
02626       return -1;
02627    }
02628 
02629    /* we have memory, so copy the old and insert the new */
02630    memcpy(*list, tmplist, (new_length-1)*sizeof(nifti1_extension));
02631 
02632    /* for some reason, I just don't like struct copy... */
02633    (*list)[new_length-1].esize = new_ext->esize;
02634    (*list)[new_length-1].ecode = new_ext->ecode;
02635    (*list)[new_length-1].edata = new_ext->edata;
02636 
02637    return 0;
02638 }
02639 
02640 
02641 /*----------------------------------------------------------------------
02642  * nifti_read_next_extension  - read a single extension from the file
02643  *
02644  * return (>= 0 is okay):
02645  *
02646  *     success      : esize
02647  *     no extension : 0
02648  *     error        : -1
02649  *----------------------------------------------------------------------*/
02650 static int nifti_read_next_extension( nifti1_extension * nex,
02651                                       nifti_image *nim, znzFile fp )
02652 {
02653    int swap = nim->byteorder != short_order();
02654    int count, size, code;
02655 
02656    /* first clear nex */
02657    nex->esize = nex->ecode = 0;
02658    nex->edata = NULL;
02659 
02660    /* must start with 4-byte size and code */
02661    count = znzread( &size, 4, 1, fp );
02662    if( count == 1 ) count = znzread( &code, 4, 1, fp );
02663 
02664    if( count != 1 ){
02665       if( gni_debug > 2 ) fprintf(stderr,"-d current extension read failed\n");
02666       return 0;       /* no extension, no error condition */
02667    }
02668 
02669    if( swap ){
02670       if( gni_debug > 2 )
02671          fprintf(stderr,"-d pre-swap exts: code = %d, size = %d\n", code, size);
02672 
02673       swap_4bytes(1, &size);
02674       swap_4bytes(1, &code);
02675    }
02676 
02677    if( gni_debug > 2 )
02678       fprintf(stderr,"-d new extensions: code = %d, size = %d\n", code, size);
02679 
02680    /* since size includes the space for size and code, it should be > 8 */
02681    if( size < 8 ){
02682       if( gni_debug > 0 )
02683          fprintf(stderr,"-d extension size cannot be less than 8: %d\n",size);
02684       return -1;
02685    } else if( size == 8 ){
02686       if( gni_debug > 1 )
02687          fprintf(stderr,"-d extension size 8 shows empty extension\n");
02688       return -1;
02689    }
02690 
02691    if( !nifti_valid_extension(nim, size, code) ) return 0;
02692 
02693    /* now get the actual data */
02694    nex->esize = size;
02695    nex->ecode = code;
02696 
02697    size -= 8;  /* subtract space for size and code in extension */
02698    nex->edata = (char *)malloc(size * sizeof(char));
02699    if( !nex->edata ){
02700       fprintf(stderr,"** failed to allocate %d bytes for extension\n",size);
02701       return -1;
02702    }
02703 
02704    count = znzread(nex->edata, 1, size, fp);
02705    if( count < size ){
02706       if( gni_debug > 0 )
02707          fprintf(stderr,"-d read only %d (of %d) bytes for extension\n",
02708                  count, size);
02709       free(nex->edata);
02710       nex->edata = NULL;
02711       return -1;
02712    }
02713 
02714    /* success! */
02715    if( gni_debug > 1 )
02716       fprintf(stderr,"+d successfully read extension, code %d, size %d\n",
02717               nex->ecode, nex->esize);
02718 
02719    return nex->esize;
02720 }
02721 
02722 /*----------------------------------------------------------------------
02723  *
02724  *----------------------------------------------------------------------*/
02725 static int nifti_valid_extension( nifti_image *nim, int size, int code )
02726 {
02727    /* first check for bad conditions */
02728    if( !nim || size <= 0 || code < 0 ){
02729       if( gni_debug > 2 )
02730          fprintf(stderr,"** NVE, bad exten params %p,%d,%d\n", nim, size, code);
02731       return 0;
02732    }
02733 
02734    if( nim->nifti_type == 3 && size > LNI_MAX_NIA_EXT_LEN ){
02735       if( gni_debug > 2 )
02736          fprintf(stderr,"** NVE, bad nifti_type 3 size %d\n", size);
02737       return 0;
02738    }
02739 
02740    /* now known, good codes */
02741    if( code == 0 ||          /* unknown, unregistered, not recommended */
02742        code == 2 ||          /* DICOM */
02743        code == 4   )         /* AFNI */
02744       return 1;
02745 
02746    if( gni_debug > 2 ) fprintf(stderr,"-d invalid extension code %d\n", code);
02747 
02748    return 0;
02749 }
02750 
02751 
02752 /*----------------------------------------------------------------------
02753  * nifti_image_load_prep  - prepare to read data
02754  *
02755  * Check nifti_image fields, open the file and seek to the appropriate
02756  * offset for reading.
02757  *
02758  * return NULL on failure
02759  *----------------------------------------------------------------------*/
02760 static znzFile nifti_image_load_prep( nifti_image *nim )
02761 {
02762    /* set up data space, open data file and seek, then call nifti_read_buffer */
02763    size_t ntot , ii , ioff;
02764    znzFile fp;
02765    char    fname[] = { "nifti_image_load_prep" };
02766 
02767    if( nim == NULL      || nim->iname == NULL ||
02768        nim->nbyper <= 0 || nim->nvox <= 0       )
02769    {
02770       if ( gni_debug > 0 ){
02771          if( !nim ) fprintf(stderr,"** ERROR: N_image_load: no nifti image\n");
02772          else fprintf(stderr,"** ERROR: N_image_load: bad params (%p,%d,%d)\n",
02773                       nim->iname, nim->nbyper, nim->nvox);
02774       }
02775       return NULL;
02776    }
02777 
02778    ntot = nifti_get_volsize(nim) ; /* total bytes to read */
02779 
02780    /** open image data file **/
02781 
02782    fp = znzopen(nim->iname , "rb",1);
02783    if( znz_isnull(fp) ){
02784       if( gni_debug > 0 )
02785          LNI_FERR(fname,"cannot open data file",nim->iname);
02786       return NULL;
02787    }
02788 
02789    /* negative offset means to figure from end of file */
02790    if( nim->iname_offset < 0 ){
02791      if( nifti_is_gzfile(nim->iname) ){
02792         if( gni_debug > 0 )
02793            LNI_FERR(fname,"negative offset for compressed file",nim->iname);
02794         znzclose(fp);
02795         return NULL;
02796      }
02797      ii = get_filesize( nim->iname ) ;
02798      if( ii <= 0 ){
02799         if( gni_debug > 0 )
02800            LNI_FERR(fname,"empty data file",nim->iname);
02801         znzclose(fp);
02802         return NULL;
02803      }
02804      ioff = (ii > ntot) ? ii-ntot : 0 ;
02805    } else {                              /* non-negative offset   */
02806      ioff = nim->iname_offset ;          /* means use it directly */
02807    }
02808    znzseek( fp , ioff , SEEK_SET ) ;
02809 
02810    return fp;
02811 }
02812 
02813 
02814 /*----------------------------------------------------------------------
02815  * Load the image data from disk into an already-prepared image struct.
02816  *
02817  * change to return an int:                    29 Nov 2004 [rickr]
02818  *    0 : success (image data space will be allocated if it wasn't already)
02819  *  < 0 : error
02820  *----------------------------------------------------------------------*/
02821 int nifti_image_load( nifti_image *nim )
02822 {
02823    /* set up data space, open data file and seek, then call nifti_read_buffer */
02824    size_t ntot , ii ;
02825    znzFile fp ;
02826 
02827    fp = nifti_image_load_prep( nim );
02828 
02829    if( fp == NULL ){
02830       if( gni_debug > 0 )
02831          fprintf(stderr,"** nifti_image_load, failed load_prep\n");
02832       return -1;
02833    }
02834 
02835    ntot = nifti_get_volsize(nim);
02836 
02837    /* if the data pointer is already set, use the given space */
02838 
02839    if( nim->data == NULL )
02840    {
02841      nim->data = (void *)calloc(1,ntot) ;  /* create image memory */
02842      if( nim->data == NULL ){
02843         if( gni_debug > 0 )
02844            fprintf(stderr,"** failed to alloc %d bytes for image data\n",
02845                    (int)ntot);
02846         znzclose(fp);
02847         return -1;
02848      }
02849    }
02850 
02851    /* now that everything is set up - do the reading */
02852    ii = nifti_read_buffer(fp,nim->data,ntot,nim);
02853    if( ii < ntot ){
02854       znzclose(fp) ;
02855       free(nim->data) ;
02856       nim->data = NULL ;
02857       return -1 ;  /* errors were printed in nifti_read_buffer() */
02858    }
02859 
02860    znzclose( fp ) ;
02861 
02862    return 0 ;
02863 }
02864 
02865 
02866 /* 30 Nov 2004 [rickr]
02867 #undef  ERREX
02868 #define ERREX(msg)                                               \
02869  do{ fprintf(stderr,"** ERROR: nifti_read_buffer: %s\n",(msg)) ;  \
02870      return 0; } while(0)
02871 */
02872 
02873 
02874 /*----------------------------------------------------------------------
02875  * reads ntot bytes of data from an open file and byte swaps if necessary
02876  * note that nifti_image is required for information on datatype, etc.
02877  *----------------------------------------------------------------------*/
02878 static size_t nifti_read_buffer(znzFile fp, void* dataptr, size_t ntot, 
02879                                 nifti_image *nim)
02880 {
02881   size_t ii;
02882 
02883   if( dataptr == NULL ){
02884      if( gni_debug > 0 )
02885         fprintf(stderr,"** ERROR: nifti_read_buffer: NULL dataptr\n");
02886      return -1;
02887   }
02888 
02889   ii = znzread( dataptr , 1 , ntot , fp ) ;             /* data input */
02890   
02891   /* if read was short, fail */
02892   if( ii < ntot ){ 
02893     if( gni_debug > 0 )
02894        fprintf(stderr,"++ WARNING: nifti_read_buffer(%s):\n"
02895                "   data bytes needed = %u\n"
02896                "   data bytes input  = %u\n"
02897                "   number missing    = %u (set to 0)\n",
02898                nim->iname , (unsigned int)ntot ,
02899                (unsigned int)ii , (unsigned int)(ntot-ii) ) ;
02900     /* memset( (char *)(dataptr)+ii , 0 , ntot-ii ) ;  now failure [rickr] */
02901     return -1 ;
02902   }
02903   
02904   /* byte swap array if needed */
02905   
02906   if( nim->swapsize > 1 && nim->byteorder != short_order() )
02907     swap_Nbytes( ntot / nim->swapsize , nim->swapsize , dataptr ) ;
02908   
02909 #ifdef isfinite
02910 {
02911   /* check input float arrays for goodness, and fix bad floats */
02912   int fix_count = 0 ;
02913   
02914   switch( nim->datatype ){
02915     
02916     case NIFTI_TYPE_FLOAT32:
02917     case NIFTI_TYPE_COMPLEX64:{
02918         register float *far = (float *)dataptr ; register int jj,nj ;
02919         nj = ntot / sizeof(float) ;
02920         for( jj=0 ; jj < nj ; jj++ )   /* count fixes 30 Nov 2004 [rickr] */
02921            if( !IS_GOOD_FLOAT(far[jj]) ){
02922               far[jj] = 0 ;
02923               fix_count++ ;
02924            }
02925       }
02926       break ;
02927     
02928     case NIFTI_TYPE_FLOAT64:
02929     case NIFTI_TYPE_COMPLEX128:{
02930         register double *far = (double *)dataptr ; register int jj,nj ;
02931         nj = ntot / sizeof(double) ;
02932         for( jj=0 ; jj < nj ; jj++ )   /* count fixes 30 Nov 2004 [rickr] */
02933            if( !IS_GOOD_FLOAT(far[jj]) ){
02934               far[jj] = 0 ;
02935               fix_count++ ;
02936            }
02937       }
02938       break ;
02939     
02940   }
02941 
02942   if( gni_debug > 1 )
02943      fprintf(stderr,"+d in image, %d bad floats were set to 0\n", fix_count);
02944 }
02945 #endif
02946   
02947   return ii;
02948 }
02949 
02950 /*--------------------------------------------------------------------------*/
02951 /* Unload the data in a nifti_image struct, but keep the metadata.
02952 ----------------------------------------------------------------------------*/
02953 
02954 void nifti_image_unload( nifti_image *nim )
02955 {
02956    if( nim != NULL && nim->data != NULL ){
02957      free(nim->data) ; nim->data = NULL ;
02958    }
02959    return ;
02960 }
02961 
02962 /*--------------------------------------------------------------------------*/
02963 /* Free a nifti_image struct that was read by nifti_image_read().
02964 ----------------------------------------------------------------------------*/
02965 
02966 void nifti_image_free( nifti_image *nim )
02967 {
02968    if( nim == NULL ) return ;
02969    if( nim->fname != NULL ) free(nim->fname) ;
02970    if( nim->iname != NULL ) free(nim->iname) ;
02971    if( nim->data  != NULL ) free(nim->data ) ;
02972    free(nim) ; return ;
02973 }
02974 
02975 /*--------------------------------------------------------------------------*/
02976 /* Print to stdout some info about a nifti_image struct.
02977 ----------------------------------------------------------------------------*/
02978 
02979 void nifti_image_infodump( nifti_image *nim )
02980 {
02981    char *str = nifti_image_to_ascii( nim ) ;
02982    /* stdout -> stderr   2 Dec 2004 [rickr] */
02983    if( str != NULL ){ fputs(str,stderr) ; free(str) ; }
02984    return ;
02985 }
02986 
02987 /*--------------------------------------------------------------------------*/
02988 /* Write a nifti_image to disk.  The following fields of nim affect how
02989    the output appears:
02990     - nifti_type = 0 ==> ANALYZE-7.5 format file pair will be written
02991     - nifti_type = 1 ==> NIFTI-1 format single file will be written
02992                          (data offset will be 348)
02993     - nifti_type = 2 ==> NIFTI_1 format file pair will be written
02994     - nifti_type = 3 ==> NIFTI_1 ASCII single file will be written
02995     - fname is the name of the output file (header or header+data)
02996     - if a file pair is being written, iname is the name of the data file
02997     - existing files WILL be overwritten with extreme prejudice
02998     - if qform_code > 0, the quatern_*, qoffset_*, and qfac fields determine
02999       the qform output, NOT the qto_xyz matrix; if you want to compute these
03000       fields from the qto_xyz matrix, you can use the utility function
03001       mat44_to_quatern()
03002 ----------------------------------------------------------------------------*/
03003 
03004 static size_t nifti_write_buffer(znzFile fp, void *buffer, size_t numbytes)
03005 {
03006    /** Write all the image data at once (no swapping here) **/
03007    size_t ss;
03008    if (znz_isnull(fp)){
03009       fprintf(stderr,"** ERROR: nifti_write_buffer: null file pointer\n");
03010       return 0;
03011    }
03012    ss = znzwrite( (void *) buffer , 1 , numbytes , fp ) ;
03013    return ss;
03014 }
03015 
03016 
03017 /* just print...
03018 #undef  ERREX
03019 #define ERREX(msg)                                                \
03020  do{ fprintf(stderr,"** ERROR: nifti_image_write: %s\n",(msg)) ;  \
03021      return ; } while(0)
03022 */
03023 
03024 static void nifti_write_all_data(znzFile fp, nifti_image *nim)
03025 {
03026    /** Write all the image data at once (no swapping here) **/
03027    size_t ss;
03028    ss = nifti_write_buffer(fp,nim->data,nim->nbyper * nim->nvox);
03029    if (ss < (nim->nbyper * nim->nvox)){
03030       fprintf(stderr,
03031          "** ERROR: nifti_image_write: wrote only %d of %d bytes to file\n",
03032          (int)ss, nim->nbyper * nim->nvox);
03033       return;
03034    }
03035 
03036    nim->byteorder = short_order() ;  /* mark as being in this CPU byte order */
03037    return ;
03038 }
03039 
03040 /* return number of extensions written, or -1 on error */
03041 static int nifti_write_extensions(znzFile fp, nifti_image *nim)
03042 {
03043    nifti1_extension * list;
03044    char               extdr[4] = { 0, 0, 0, 0 };
03045    int                c, size, ok = 1;
03046 
03047    if( znz_isnull(fp) || !nim || nim->num_ext < 0 ){
03048       if( gni_debug > 0 )
03049          fprintf(stderr,"** nifti_write_extensions, bad params\n");
03050       return -1;
03051    }
03052 
03053    /* write out extender block */
03054    if( nim->num_ext > 0 ) extdr[0] = 1;
03055    if( nifti_write_buffer(fp, extdr, 4) != 4 ){
03056       fprintf(stderr,"** failed to write extender\n");
03057       return -1;
03058    }
03059 
03060    list = nim->ext_list;
03061    for ( c = 0; c < nim->num_ext; c++ ){
03062       size = nifti_write_buffer(fp, &list->esize, sizeof(int));
03063       ok = (size == (int)sizeof(int));
03064       if( ok )
03065          size = nifti_write_buffer(fp, &list->ecode, sizeof(int));
03066       ok = (size == (int)sizeof(int));
03067       if( ok )
03068          size = nifti_write_buffer(fp, list->edata, list->esize);
03069 
03070       if( !ok ){
03071          fprintf(stderr,"** failed while writing extension #%d\n",c);
03072          return -1;
03073       }
03074 
03075       list++;
03076    }
03077 
03078    if( gni_debug > 1 )
03079       fprintf(stderr,"+d wrote out %d extensions\n", nim->num_ext);
03080 
03081    return nim->num_ext;
03082 }
03083 
03084 
03085 nifti_image* nifti_simple_init_nim()
03086 {
03087   nifti_image *nim;
03088   struct nifti_1_header nhdr;
03089   int nbyper, swapsize;
03090   
03091   memset(&nhdr,0,sizeof(nhdr)) ;  /* zero out header, to be safe */
03092   
03093    /** load the ANALYZE-7.5 generic parts of the header struct **/
03094 
03095    nhdr.sizeof_hdr = sizeof(nhdr) ;
03096    nhdr.regular    = 'r' ;             /* for some stupid reason */
03097 
03098    nhdr.dim[0] = 3 ;
03099    nhdr.dim[1] = 1 ; nhdr.dim[2] = 1 ; nhdr.dim[3] = 1 ;
03100    nhdr.dim[4] = 0 ;
03101 
03102    nhdr.pixdim[0] = 0.0 ;
03103    nhdr.pixdim[1] = 1.0 ; nhdr.pixdim[2] = 1.0 ;
03104    nhdr.pixdim[3] = 1.0 ;
03105 
03106    nhdr.datatype = NIFTI_TYPE_FLOAT32 ;
03107    nifti_datatype_sizes( nhdr.datatype , &nbyper, &swapsize );
03108    nhdr.bitpix   = 8 * nbyper ;
03109 
03110    nim = nifti_convert_nhdr2nim(nhdr,NULL);
03111    nim->fname = NULL;
03112    nim->iname = NULL;
03113    return nim;
03114 }
03115 
03116 
03117 
03118 
03119 struct nifti_1_header nifti_convert_nim2nhdr(nifti_image* nim)
03120 {
03121   struct nifti_1_header nhdr;
03122 
03123    memset(&nhdr,0,sizeof(nhdr)) ;  /* zero out header, to be safe */
03124 
03125 
03126    /** load the ANALYZE-7.5 generic parts of the header struct **/
03127 
03128    nhdr.sizeof_hdr = sizeof(nhdr) ;
03129    nhdr.regular    = 'r' ;             /* for some stupid reason */
03130 
03131    nhdr.dim[0] = nim->ndim ;
03132    nhdr.dim[1] = nim->nx ; nhdr.dim[2] = nim->ny ; nhdr.dim[3] = nim->nz ;
03133    nhdr.dim[4] = nim->nt ; nhdr.dim[5] = nim->nu ; nhdr.dim[6] = nim->nv ;
03134    nhdr.dim[7] = nim->nw ;
03135 
03136    nhdr.pixdim[0] = 0.0 ;
03137    nhdr.pixdim[1] = nim->dx ; nhdr.pixdim[2] = nim->dy ;
03138    nhdr.pixdim[3] = nim->dz ; nhdr.pixdim[4] = nim->dt ;
03139    nhdr.pixdim[5] = nim->du ; nhdr.pixdim[6] = nim->dv ;
03140    nhdr.pixdim[7] = nim->dw ;
03141 
03142    nhdr.datatype = nim->datatype ;
03143    nhdr.bitpix   = 8 * nim->nbyper ;
03144 
03145    if( nim->cal_max > nim->cal_min ){
03146      nhdr.cal_max = nim->cal_max ;
03147      nhdr.cal_min = nim->cal_min ;
03148    }
03149 
03150    if( nim->scl_slope != 0.0 ){
03151      nhdr.scl_slope = nim->scl_slope ;
03152      nhdr.scl_inter = nim->scl_inter ;
03153    }
03154 
03155    if( nim->descrip[0] != '\0' ){
03156      memcpy(nhdr.descrip ,nim->descrip ,79) ; nhdr.descrip[79] = '\0' ;
03157    }
03158    if( nim->aux_file[0] != '\0' ){
03159      memcpy(nhdr.aux_file ,nim->aux_file ,23) ; nhdr.aux_file[23] = '\0' ;
03160    }
03161 
03162    /** Load NIFTI specific stuff into the header **/
03163 
03164    if( nim->nifti_type > 0 ){
03165 
03166      if( nim->nifti_type == 1 ) strcpy(nhdr.magic,"n+1") ;   /* 1 file */
03167      else                       strcpy(nhdr.magic,"ni1") ;   /* 2 files */
03168 
03169      /* for nifti files, enforce positive pixdims! */
03170      nhdr.pixdim[1] = fabs(nhdr.pixdim[1]) ; nhdr.pixdim[2] = fabs(nhdr.pixdim[2]) ;
03171      nhdr.pixdim[3] = fabs(nhdr.pixdim[3]) ; nhdr.pixdim[4] = fabs(nhdr.pixdim[4]) ;
03172      nhdr.pixdim[5] = fabs(nhdr.pixdim[5]) ; nhdr.pixdim[6] = fabs(nhdr.pixdim[6]) ;
03173      nhdr.pixdim[7] = fabs(nhdr.pixdim[7]) ;
03174 
03175      nhdr.intent_code = nim->intent_code ;
03176      nhdr.intent_p1   = nim->intent_p1 ;
03177      nhdr.intent_p2   = nim->intent_p2 ;
03178      nhdr.intent_p3   = nim->intent_p3 ;
03179      if( nim->intent_name[0] != '\0' ){
03180        memcpy(nhdr.intent_name,nim->intent_name,15) ;
03181        nhdr.intent_name[15] = '\0' ;
03182      }
03183 
03184      nhdr.vox_offset  = (float) nim->iname_offset ;
03185      nhdr.xyzt_units  = SPACE_TIME_TO_XYZT( nim->xyz_units, nim->time_units ) ;
03186      nhdr.toffset     = nim->toffset ;
03187 
03188      if( nim->qform_code > 0 ){
03189        nhdr.qform_code = nim->qform_code ;
03190        nhdr.quatern_b  = nim->quatern_b ;
03191        nhdr.quatern_c  = nim->quatern_c ;
03192        nhdr.quatern_d  = nim->quatern_d ;
03193        nhdr.qoffset_x  = nim->qoffset_x ;
03194        nhdr.qoffset_y  = nim->qoffset_y ;
03195        nhdr.qoffset_z  = nim->qoffset_z ;
03196        nhdr.pixdim[0]  = (nim->qfac >= 0.0) ? 1.0 : -1.0 ;
03197      }
03198 
03199      if( nim->sform_code > 0 ){
03200        nhdr.sform_code = nim->sform_code ;
03201        nhdr.srow_x[0]  = nim->sto_xyz.m[0][0] ;
03202        nhdr.srow_x[1]  = nim->sto_xyz.m[0][1] ;
03203        nhdr.srow_x[2]  = nim->sto_xyz.m[0][2] ;
03204        nhdr.srow_x[3]  = nim->sto_xyz.m[0][3] ;
03205        nhdr.srow_y[0]  = nim->sto_xyz.m[1][0] ;
03206        nhdr.srow_y[1]  = nim->sto_xyz.m[1][1] ;
03207        nhdr.srow_y[2]  = nim->sto_xyz.m[1][2] ;
03208        nhdr.srow_y[3]  = nim->sto_xyz.m[1][3] ;
03209        nhdr.srow_z[0]  = nim->sto_xyz.m[2][0] ;
03210        nhdr.srow_z[1]  = nim->sto_xyz.m[2][1] ;
03211        nhdr.srow_z[2]  = nim->sto_xyz.m[2][2] ;
03212        nhdr.srow_z[3]  = nim->sto_xyz.m[2][3] ;
03213      }
03214 
03215      nhdr.dim_info = FPS_INTO_DIM_INFO( nim->freq_dim ,
03216                                         nim->phase_dim , nim->slice_dim ) ;
03217      nhdr.slice_code     = nim->slice_code ;
03218      nhdr.slice_start    = nim->slice_start ;
03219      nhdr.slice_end      = nim->slice_end ;
03220      nhdr.slice_duration = nim->slice_duration ;
03221    }
03222 
03223    return nhdr;
03224 }
03225 
03226 
03227 
03228 int nifti_extension_size(nifti_image *nim)
03229 {
03230    int c, size = 0;
03231 
03232    if( !nim || nim->num_ext <= 0 ) return 0;
03233 
03234    if( gni_debug > 2 ) fprintf(stderr,"-d ext sizes:");
03235 
03236    for ( c = 0; c < nim->num_ext; c++ ){
03237       size += nim->ext_list[c].esize;
03238       if( gni_debug > 2 ) fprintf(stderr,"  %d",nim->ext_list[c].esize);
03239    }
03240 
03241    if( gni_debug > 2 ) fprintf(stderr," (total = %d)\n",size);
03242 
03243    return size;
03244 }
03245 
03246 void nifti_set_iname_offset(nifti_image *nim)
03247 {
03248    int offset = nifti_extension_size(nim);  /* init based on extensions */
03249 
03250 
03251    switch( nim->nifti_type ){
03252 
03253      default:  /* writing into 2 files */
03254        /* we only write files with 0 offset in the 2 file format */
03255        nim->iname_offset = 0 ;
03256      break ;
03257 
03258      case 1:   /* NIFTI-1 single binary file */
03259        if (nim->iname_offset < sizeof(struct nifti_1_header))  {
03260            offset += sizeof(struct nifti_1_header) + 4 ;
03261            /* be sure offset is aligned to a 16 byte word boundary */
03262            if ( ( offset % 16 ) != 0 )  offset = ((offset + 0xf) & ~0xf);
03263 
03264            if( nim->iname_offset != offset && gni_debug > 1 ){
03265               fprintf(stderr,"+d changing offset from %d to %d\n",
03266                       nim->iname_offset, offset);
03267            }
03268            nim->iname_offset = offset;
03269        }
03270      break ;
03271 
03272                /* non-standard case: */
03273      case 3:{  /* NIFTI-1 ASCII header + binary data (single file) */
03274        nim->iname_offset = -1 ;              /* compute offset from filesize */
03275      }
03276    }
03277 }
03278 
03279 
03280 
03281 #undef  ERREX
03282 #define ERREX(msg)                                                \
03283  do{ fprintf(stderr,"** ERROR: nifti_image_write_hdr_img: %s\n",(msg)) ;  \
03284      return fp ; } while(0)
03285 
03286 
03287 /* ----------------------------------------------------------------------
03288  * This writes the header (and optionally the image data) to file
03289  * If the image data file is left open it returns a valid znzFile handle
03290  * It also uses imgfile as the open image file is not null, and modifies
03291  * it inside.
03292  * 
03293  * Values for write_data mode are based on two binary flags
03294  * ( 0/1 for no-write/write data, and 0/2 for close/leave-open files ) :
03295  *       0 = do not write data and close (do not open data file)
03296  *       1 = write data        and close
03297  *       2 = do not write data and leave data file open 
03298  *       3 = write data        and leave data file open 
03299  * ----------------------------------------------------------------------*/
03300 
03301 static znzFile nifti_image_write_hdr_img2( nifti_image *nim , int write_data , 
03302                                            char* opts, znzFile *imgfile )
03303 {
03304    struct nifti_1_header nhdr ;
03305    znzFile fp=NULL, hdrfile=NULL;
03306    size_t ss ;
03307 
03308    if( nim        == NULL                         ) ERREX("NULL input") ;
03309    if( !nifti_validfilename(nim->fname)           ) ERREX("bad fname input") ;
03310    if( (nim->data  == NULL)  && ((write_data & 1)!=0) ) ERREX("no image data") ;
03311 
03312    nifti_set_iname_offset(nim);
03313 
03314    /* make iname from fname, if needed */
03315 
03316    switch( nim->nifti_type ){
03317 
03318      default:  /* writing into 2 files */
03319        if( nim->iname != NULL && strcmp(nim->iname,nim->fname) == 0 ){
03320          free(nim->iname) ; nim->iname = NULL ;
03321        }
03322        if( nim->iname == NULL ){ 
03323          /* choose a new name because either no name set,
03324           * or it wasn't different from hdr */
03325          nim->iname = nifti_findimgname(nim->fname,nim->nifti_type);
03326          if( nim->iname == NULL ){
03327             if( gni_debug > 0 )
03328                fprintf(stderr,"** failed findimgname for '%s'\n", nim->fname);
03329                return NULL;  
03330          }
03331        }
03332      break ;
03333 
03334      case 1:   /* NIFTI-1 single binary file */
03335      break ;
03336 
03337                /* non-standard case: */
03338      case 3:{  /* NIFTI-1 ASCII header + binary data (single file) */
03339        char *hstr ;
03340        nim->byteorder = short_order() ;      /* am writing in current order */
03341        hstr = nifti_image_to_ascii( nim ) ;  /* get header in ASCII form */
03342        if( hstr == NULL ) ERREX("bad ASCII header creation?") ;
03343        fp = znzopen( nim->fname , opts , nifti_is_gzfile(nim->fname) ) ;
03344        if( znz_isnull(fp) ){ free(hstr); ERREX("can't open output file"); }
03345        znzputs(hstr,fp) ;
03346 
03347        nifti_write_extensions(fp,nim);
03348 
03349        /* writes the binary data to fp */
03350        if ( (write_data & 1)!=0) { nifti_write_all_data(fp,nim); }
03351        if ( (write_data & 2)==0) { znzclose(fp); }
03352        return fp;  /* returned but may be closed */
03353      }
03354    }
03355      
03356    /***** Here -- write a binary header *****/
03357    
03358    nhdr = nifti_convert_nim2nhdr(nim);
03359 
03360    if (imgfile==NULL) {
03361      
03362      /** Open file, write header **/
03363      
03364      fp = znzopen( nim->fname , opts , nifti_is_gzfile(nim->fname) ) ;
03365      if( znz_isnull(fp) ) ERREX("can't open output file") ;
03366      
03367      ss = znzwrite( &nhdr , 1 , sizeof(nhdr) , fp ) ;
03368      if( ss < sizeof(nhdr) ){
03369        znzclose(fp) ; ERREX("bad write to output file") ;
03370      }
03371      nifti_write_extensions(fp,nim);
03372      
03373      
03374      /** if writing data or keeping data file open **/
03375      if ((write_data & 3)!=0) {
03376        /** If writing dual files, close header and open image file **/
03377        if( nim->nifti_type != 1 ){
03378          znzclose(fp) ;
03379          fp = znzopen( nim->iname , opts , nifti_is_gzfile(nim->iname) ) ;
03380          if( znz_isnull(fp) ) ERREX("can't open image file") ;
03381        }
03382        /* skip to vox_offset, ready for writing */
03383        znzseek(fp,nim->iname_offset,SEEK_SET);
03384        if ( (write_data & 1)!=0)  nifti_write_all_data(fp,nim);
03385      }
03386      
03387      /** close the file if requested **/
03388      if ( (write_data & 2)==0) { znzclose(fp); }
03389      return fp;  /* returned but may be closed */
03390      
03391    }
03392 
03393    /** ----- otherwise use imgfile for the image -----**/
03394 
03395    /** write header **/
03396 
03397    if (nim->nifti_type==1) {
03398      if( znz_isnull(*imgfile) ) ERREX("bad image data file passed in") ;
03399      /* if header and data file are the same then seek to beginning and write */
03400      znzseek(*imgfile,0,SEEK_SET);
03401      ss = znzwrite( &nhdr , 1 , sizeof(nhdr) , *imgfile ) ;
03402      if( ss < sizeof(nhdr) ){ ERREX("bad write to output file") ; }
03403      nifti_write_extensions(*imgfile,nim);
03404    } else {
03405      /* if a dual file type or no file opened, then start a new file */
03406      hdrfile = znzopen( nim->fname , opts , nifti_is_gzfile(nim->fname) ) ;
03407      if( znz_isnull(hdrfile) ) ERREX("can't open output file") ;
03408      /* if the header file was separate then write and close it now */
03409      ss = znzwrite( &nhdr , 1 , sizeof(nhdr) , hdrfile ) ;
03410      if( ss < sizeof(nhdr) ){ znzclose(fp); ERREX("bad write to output file"); }
03411      nifti_write_extensions(hdrfile,nim);
03412      znzclose(hdrfile);
03413    }
03414 
03415 
03416    /** if writing data or keeping data file open **/
03417    if ((write_data & 3)!=0) {  
03418      /* skip to vox_offset, ready for writing in image file */
03419      znzseek(*imgfile,nim->iname_offset,SEEK_SET);
03420      if ( (write_data & 1)!=0) nifti_write_all_data(*imgfile,nim);
03421    }
03422 
03423    /** close the file if requested **/
03424    if ( (write_data & 2)==0) { znzclose(*imgfile); }
03425    return *imgfile;  /* returned but may be closed */
03426 }
03427 
03428 
03429 static znzFile nifti_image_write_hdr_img( nifti_image *nim , int write_data , 
03430                                           char* opts)
03431 {
03432   return nifti_image_write_hdr_img2(nim,write_data,opts,NULL);
03433 }
03434 
03435 
03436 void nifti_image_write( nifti_image *nim )
03437 {
03438   nifti_image_write_hdr_img(nim,1,"wb");
03439 }
03440 
03441 
03442 
03443 /* copy for nifti_image is via the nifti_1_header structure */
03444 /* it does not copy data */
03445 
03446 nifti_image * nifti_copy_nim_info(nifti_image* src)
03447 {
03448   struct nifti_1_header nhdr;
03449   nifti_image *dest;
03450   dest = (nifti_image *)calloc(1,sizeof(nifti_image));
03451   nhdr = nifti_convert_nim2nhdr(src);
03452   dest = nifti_convert_nhdr2nim(nhdr,src->fname);
03453   return dest;
03454 }
03455 
03456 
03457 /*------------------------------------------------------------------------*/
03458 /* Un-escape a C string in place -- that is, convert XML escape sequences
03459    back into their characters.  (This can be done in place since the
03460    replacement is always smaller than the input.)  Escapes recognized are:
03461      -  &lt;   ->  <
03462      -  &gt;   ->  >
03463      -  &quot; ->  "
03464      -  &apos; ->  '
03465      -  &amp;  ->  &
03466    Also replace CR LF pair (Microsoft), or CR alone (Macintosh) with
03467    LF (Unix), per the XML standard.
03468    Return value is number of replacements made (if you care).
03469 --------------------------------------------------------------------------*/
03470 
03471 #undef  CR
03472 #undef  LF
03473 #define CR 0x0D
03474 #define LF 0x0A
03475 
03476 int unescape_string( char *str )
03477 {
03478    int ii,jj , nn,ll ;
03479 
03480    if( str == NULL ) return 0 ;                /* no string? */
03481    ll = strlen(str) ; if( ll == 0 ) return 0 ;
03482 
03483    /* scan for escapes: &something; */
03484 
03485    for( ii=jj=nn=0 ; ii<ll ; ii++,jj++ ){ /* scan at ii; results go in at jj */
03486 
03487      if( str[ii] == '&' ){  /* start of escape? */
03488 
03489              if( ii+3 < ll        &&   /* &lt; */
03490                  str[ii+1] == 'l' &&
03491                  str[ii+2] == 't' &&
03492                  str[ii+3] == ';'   ){ str[jj] = '<' ; ii += 3 ; nn++ ; }
03493 
03494         else if( ii+3 < ll        &&   /* &gt; */
03495                  str[ii+1] == 'g' &&
03496                  str[ii+2] == 't' &&
03497                  str[ii+3] == ';'   ){ str[jj] = '>' ; ii += 3 ; nn++ ; }
03498 
03499         else if( ii+5 < ll        &&   /* &quot; */
03500                  str[ii+1] == 'q' &&
03501                  str[ii+2] == 'u' &&
03502                  str[ii+3] == 'o' &&
03503                  str[ii+4] == 't' &&
03504                  str[ii+5] == ';'   ){ str[jj] = '"' ; ii += 5 ; nn++ ; }
03505 
03506         else if( ii+5 < ll        &&   /* &apos; */
03507                  str[ii+1] == 'a' &&
03508                  str[ii+2] == 'p' &&
03509                  str[ii+3] == 'o' &&
03510                  str[ii+4] == 's' &&
03511                  str[ii+5] == ';'   ){ str[jj] = '\'' ; ii += 5 ; nn++ ; }
03512 
03513         else if( ii+4 < ll        &&  /* &amp; */
03514                  str[ii+1] == 'a' &&
03515                  str[ii+2] == 'm' &&
03516                  str[ii+3] == 'p' &&
03517                  str[ii+4] == ';'   ){ str[jj] = '&' ; ii += 4 ; nn++ ; }
03518 
03519         /* although the comments above don't mention it,
03520            we also look for XML style numeric escapes
03521            of the forms &#32; (decimal) and &#xfd; (hex) */
03522 
03523         else if( ii+3 < ll        &&
03524                  str[ii+1] == '#' &&
03525                  isdigit(str[ii+2]) ){   /* &#dec; */
03526 
03527            unsigned int val='?' ; int kk=ii+3 ;
03528            while( kk < ll && kk != ';' ) kk++ ;
03529            sscanf( str+ii+2 , "%u" , &val ) ;
03530            str[jj] = (char) val ; ii = kk ; nn++ ;
03531         }
03532 
03533         else if( ii+4 < ll        &&
03534                  str[ii+1] == '#' &&
03535                  str[ii+2] == 'x' &&
03536                  isxdigit(str[ii+3]) ){   /* &#hex; */
03537 
03538            unsigned int val='?' ; int kk=ii+4 ;
03539            while( kk < ll && kk != ';' ) kk++ ;
03540            sscanf( str+ii+3 , "%x" , &val ) ;
03541            str[jj] = (char) val ; ii = kk ; nn++ ;
03542         }
03543 
03544         /* didn't start a recognized escape, so just copy as normal */
03545 
03546         else if( jj < ii ){ str[jj] = str[ii] ; }
03547 
03548      } else if( str[ii] == CR ) {  /* is a carriage return */
03549 
03550         if( str[ii+1] == LF ){ str[jj] = LF ; ii++ ; nn++ ; }  /* CR LF */
03551         else                 { str[jj] = LF ;      ; nn++ ; }  /* CR only */
03552 
03553      } else { /* is a normal character, just copy to output */
03554 
03555              if( jj < ii ){ str[jj] = str[ii] ; }
03556      }
03557 
03558      /* at this point, ii=index of last character used up in scan
03559                        jj=index of last character written to (jj <= ii) */
03560    }
03561 
03562    if( jj < ll ) str[jj] = '\0' ; /* end string properly */
03563 
03564    return nn ;
03565 }
03566 
03567 /*------------------------------------------------------------------------*/
03568 /* Quotize (and escapize) one string, returning a new string.
03569    Approximately speaking, this is the inverse of unescape_string().
03570    The result should be free()-ed when you are done with it.
03571 --------------------------------------------------------------------------*/
03572 
03573 char *escapize_string( char *str )
03574 {
03575    int ii,jj , lstr,lout ;
03576    char *out ;
03577 
03578    if( str == NULL || (lstr=strlen(str)) == 0 ){      /* 0 length */
03579      out = nifti_strdup("''") ; return out ;                /* string?? */
03580    }
03581 
03582    lout = 4 ;                      /* initialize length of output */
03583    for( ii=0 ; ii < lstr ; ii++ ){ /* count characters for output */
03584      switch( str[ii] ){
03585        case '&':  lout += 5 ; break ;  /* replace '&' with "&amp;" */
03586 
03587        case '<':
03588        case '>':  lout += 4 ; break ;  /* replace '<' with "&lt;" */
03589 
03590        case '"' :
03591        case '\'': lout += 6 ; break ;  /* replace '"' with "&quot;" */
03592 
03593        case CR:
03594        case LF:   lout += 6 ; break ;  /* replace CR with "&#x0d;"
03595                                                   LF with "&#x0a;" */
03596 
03597        default: lout++ ; break ;      /* copy all other chars */
03598      }
03599    }
03600    out = (char *)calloc(1,lout) ;     /* allocate output string */
03601    out[0] = '\'' ;                    /* opening quote mark */
03602    for( ii=0,jj=1 ; ii < lstr ; ii++ ){
03603       switch( str[ii] ){
03604          default: out[jj++] = str[ii] ; break ;  /* normal characters */
03605 
03606          case '&':  memcpy(out+jj,"&amp;",5)  ; jj+=5 ; break ;
03607 
03608          case '<':  memcpy(out+jj,"&lt;",4)   ; jj+=4 ; break ;
03609          case '>':  memcpy(out+jj,"&gt;",4)   ; jj+=4 ; break ;
03610 
03611          case '"' : memcpy(out+jj,"&quot;",6) ; jj+=6 ; break ;
03612 
03613          case '\'': memcpy(out+jj,"&apos;",6) ; jj+=6 ; break ;
03614 
03615          case CR:   memcpy(out+jj,"&#x0d;",6) ; jj+=6 ; break ;
03616          case LF:   memcpy(out+jj,"&#x0a;",6) ; jj+=6 ; break ;
03617       }
03618    }
03619    out[jj++] = '\''  ;  /* closing quote mark */
03620    out[jj]   = '\0' ;  /* terminate the string */
03621    return out ;
03622 }
03623 
03624 /*---------------------------------------------------------------------------*/
03625 /* Dump the information in a NIFTI image header to an XML-ish ASCII string
03626    that can later be converted back into a NIFTI header in
03627    nifti_image_from_ascii().  The resulting string can be free()-ed when
03628    you are done with it.
03629 -----------------------------------------------------------------------------*/
03630 
03631 char *nifti_image_to_ascii( nifti_image *nim )
03632 {
03633    char *buf , *ebuf ; int nbuf ;
03634 
03635    if( nim == NULL ) return NULL ;   /* stupid caller */
03636 
03637    buf = (char *)calloc(1,65534); nbuf = 0;  /* longer than needed, to be safe */
03638 
03639    sprintf( buf , "<nifti_image\n" ) ;   /* XML-ish opener */
03640 
03641    sprintf( buf+strlen(buf) , "  nifti_type = '%s'\n" ,
03642               (nim->nifti_type == 1) ? "NIFTI-1+"
03643              :(nim->nifti_type == 2) ? "NIFTI-1"
03644              :(nim->nifti_type == 3) ? "NIFTI-1A"
03645              :                         "ANALYZE-7.5" ) ;
03646 
03647    /** Strings that we don't control (filenames, etc.) that might
03648        contain "weird" characters (like quotes) are "escaped":
03649        - A few special characters are replaced by XML-style escapes, using
03650          the function escapize_string().
03651        - On input, function unescape_string() reverses this process.
03652        - The result is that the NIFTI ASCII-format header is XML-compliant. **/
03653 
03654    ebuf = escapize_string(nim->fname) ;
03655    sprintf( buf+strlen(buf) , "  header_filename = %s\n",ebuf); free(ebuf);
03656 
03657    ebuf = escapize_string(nim->iname) ;
03658    sprintf( buf+strlen(buf) , "  image_filename = %s\n", ebuf); free(ebuf);
03659 
03660    sprintf( buf+strlen(buf) , "  image_offset = '%d'\n" , nim->iname_offset );
03661 
03662                        sprintf( buf+strlen(buf), "  ndim = '%d'\n", nim->ndim);
03663                        sprintf( buf+strlen(buf), "  nx = '%d'\n",   nim->nx  );
03664    if( nim->ndim > 1 ) sprintf( buf+strlen(buf), "  ny = '%d'\n",   nim->ny  );
03665    if( nim->ndim > 2 ) sprintf( buf+strlen(buf), "  nz = '%d'\n",   nim->nz  );
03666    if( nim->ndim > 3 ) sprintf( buf+strlen(buf), "  nt = '%d'\n",   nim->nt  );
03667    if( nim->ndim > 4 ) sprintf( buf+strlen(buf), "  nu = '%d'\n",   nim->nu  );
03668    if( nim->ndim > 5 ) sprintf( buf+strlen(buf), "  nv = '%d'\n",   nim->nv  );
03669    if( nim->ndim > 6 ) sprintf( buf+strlen(buf), "  nw = '%d'\n",   nim->nw  );
03670                        sprintf( buf+strlen(buf), "  dx = '%g'\n",   nim->dx  );
03671    if( nim->ndim > 1 ) sprintf( buf+strlen(buf), "  dy = '%g'\n",   nim->dy  );
03672    if( nim->ndim > 2 ) sprintf( buf+strlen(buf), "  dz = '%g'\n",   nim->dz  );
03673    if( nim->ndim > 3 ) sprintf( buf+strlen(buf), "  dt = '%g'\n",   nim->dt  );
03674    if( nim->ndim > 4 ) sprintf( buf+strlen(buf), "  du = '%g'\n",   nim->du  );
03675    if( nim->ndim > 5 ) sprintf( buf+strlen(buf), "  dv = '%g'\n",   nim->dv  );
03676    if( nim->ndim > 6 ) sprintf( buf+strlen(buf), "  dw = '%g'\n",   nim->dw  );
03677 
03678    sprintf( buf+strlen(buf) , "  datatype = '%d'\n" , nim->datatype ) ;
03679    sprintf( buf+strlen(buf) , "  datatype_name = '%s'\n" ,
03680                               nifti_datatype_string(nim->datatype) ) ;
03681 
03682    sprintf( buf+strlen(buf) , "  nvox = '%d'\n" , nim->nvox ) ;
03683    sprintf( buf+strlen(buf) , "  nbyper = '%d'\n" , nim->nbyper ) ;
03684 
03685    sprintf( buf+strlen(buf) , "  byteorder = '%s'\n" ,
03686             (nim->byteorder==MSB_FIRST) ? "MSB_FIRST" : "LSB_FIRST" ) ;
03687 
03688    if( nim->cal_min < nim->cal_max ){
03689      sprintf( buf+strlen(buf) , "  cal_min = '%g'\n", nim->cal_min ) ;
03690      sprintf( buf+strlen(buf) , "  cal_max = '%g'\n", nim->cal_max ) ;
03691    }
03692 
03693    if( nim->scl_slope != 0.0 ){
03694      sprintf( buf+strlen(buf) , "  scl_slope = '%g'\n" , nim->scl_slope ) ;
03695      sprintf( buf+strlen(buf) , "  scl_inter = '%g'\n" , nim->scl_inter ) ;
03696    }
03697 
03698    if( nim->intent_code > 0 ){
03699      sprintf( buf+strlen(buf) , "  intent_code = '%d'\n", nim->intent_code ) ;
03700      sprintf( buf+strlen(buf) , "  intent_code_name = '%s'\n" ,
03701                                 nifti_intent_string(nim->intent_code) ) ;
03702      sprintf( buf+strlen(buf) , "  intent_p1 = '%g'\n" , nim->intent_p1 ) ;
03703      sprintf( buf+strlen(buf) , "  intent_p2 = '%g'\n" , nim->intent_p2 ) ;
03704      sprintf( buf+strlen(buf) , "  intent_p3 = '%g'\n" , nim->intent_p3 ) ;
03705 
03706      if( nim->intent_name[0] != '\0' ){
03707        ebuf = escapize_string(nim->intent_name) ;
03708        sprintf( buf+strlen(buf) , "  intent_name = %s\n",ebuf) ;
03709        free(ebuf) ;
03710      }
03711    }
03712 
03713    if( nim->toffset != 0.0 )
03714      sprintf( buf+strlen(buf) , "  toffset = '%g'\n",nim->toffset ) ;
03715 
03716    if( nim->xyz_units > 0 )
03717      sprintf( buf+strlen(buf) ,
03718               "  xyz_units = '%d'\n"
03719               "  xyz_units_name = '%s'\n" ,
03720               nim->xyz_units , nifti_units_string(nim->xyz_units) ) ;
03721 
03722    if( nim->time_units > 0 )
03723      sprintf( buf+strlen(buf) ,
03724               "  time_units = '%d'\n"
03725               "  time_units_name = '%s'\n" ,
03726               nim->time_units , nifti_units_string(nim->time_units) ) ;
03727 
03728    if( nim->freq_dim > 0 )
03729      sprintf( buf+strlen(buf) , "  freq_dim = '%d'\n",nim->freq_dim ) ;
03730    if( nim->phase_dim > 0 )
03731      sprintf( buf+strlen(buf) , "  phase_dim = '%d'\n",nim->phase_dim ) ;
03732    if( nim->slice_dim > 0 )
03733      sprintf( buf+strlen(buf) , "  slice_dim = '%d'\n",nim->slice_dim ) ;
03734    if( nim->slice_code > 0 )
03735      sprintf( buf+strlen(buf) ,
03736               "  slice_code = '%d'\n"
03737               "  slice_code_name = '%s'\n" ,
03738               nim->slice_code , nifti_slice_string(nim->slice_code) ) ;
03739    if( nim->slice_start >= 0 && nim->slice_end > nim->slice_start )
03740      sprintf( buf+strlen(buf) ,
03741               "  slice_start = '%d'\n"
03742               "  slice_end = '%d'\n"  , nim->slice_start , nim->slice_end ) ;
03743    if( nim->slice_duration != 0.0 )
03744      sprintf( buf+strlen(buf) , "  slice_duration = '%g'\n",
03745               nim->slice_duration ) ;
03746 
03747    if( nim->descrip[0] != '\0' ){
03748      ebuf = escapize_string(nim->descrip) ;
03749      sprintf( buf+strlen(buf) , "  descrip = %s\n",ebuf) ;
03750      free(ebuf) ;
03751    }
03752 
03753    if( nim->aux_file[0] != '\0' ){
03754      ebuf = escapize_string(nim->aux_file) ;
03755      sprintf( buf+strlen(buf) , "  aux_file = %s\n",ebuf) ;
03756      free(ebuf) ;
03757    }
03758 
03759    if( nim->qform_code > 0 ){
03760      int i,j,k ;
03761 
03762      sprintf( buf+strlen(buf) ,
03763               "  qform_code = '%d'\n"
03764               "  qform_code_name = '%s'\n"
03765      "  qto_xyz_matrix = '%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g'\n" ,
03766          nim->qform_code      , nifti_xform_string(nim->qform_code) ,
03767          nim->qto_xyz.m[0][0] , nim->qto_xyz.m[0][1] ,
03768          nim->qto_xyz.m[0][2] , nim->qto_xyz.m[0][3] ,
03769          nim->qto_xyz.m[1][0] , nim->qto_xyz.m[1][1] ,
03770          nim->qto_xyz.m[1][2] , nim->qto_xyz.m[1][3] ,
03771          nim->qto_xyz.m[2][0] , nim->qto_xyz.m[2][1] ,
03772          nim->qto_xyz.m[2][2] , nim->qto_xyz.m[2][3] ,
03773          nim->qto_xyz.m[3][0] , nim->qto_xyz.m[3][1] ,
03774          nim->qto_xyz.m[3][2] , nim->qto_xyz.m[3][3]  ) ;
03775 
03776      sprintf( buf+strlen(buf) ,
03777      "  qto_ijk_matrix = '%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g'\n" ,
03778          nim->qto_ijk.m[0][0] , nim->qto_ijk.m[0][1] ,
03779          nim->qto_ijk.m[0][2] , nim->qto_ijk.m[0][3] ,
03780          nim->qto_ijk.m[1][0] , nim->qto_ijk.m[1][1] ,
03781          nim->qto_ijk.m[1][2] , nim->qto_ijk.m[1][3] ,
03782          nim->qto_ijk.m[2][0] , nim->qto_ijk.m[2][1] ,
03783          nim->qto_ijk.m[2][2] , nim->qto_ijk.m[2][3] ,
03784          nim->qto_ijk.m[3][0] , nim->qto_ijk.m[3][1] ,
03785          nim->qto_ijk.m[3][2] , nim->qto_ijk.m[3][3]  ) ;
03786 
03787      sprintf( buf+strlen(buf) ,
03788               "  quatern_b = '%g'\n"
03789               "  quatern_c = '%g'\n"
03790               "  quatern_d = '%g'\n"
03791               "  qoffset_x = '%g'\n"
03792               "  qoffset_y = '%g'\n"
03793               "  qoffset_z = '%g'\n"
03794               "  qfac = '%g'\n" ,
03795          nim->quatern_b , nim->quatern_c , nim->quatern_d ,
03796          nim->qoffset_x , nim->qoffset_y , nim->qoffset_z , nim->qfac ) ;
03797 
03798      mat44_to_orientation( nim->qto_xyz , &i,&j,&k ) ;
03799      if( i > 0 && j > 0 && k > 0 )
03800        sprintf( buf+strlen(buf) ,
03801                 "  qform_i_orientation = '%s'\n"
03802                 "  qform_j_orientation = '%s'\n"
03803                 "  qform_k_orientation = '%s'\n" ,
03804                 nifti_orientation_string(i) ,
03805                 nifti_orientation_string(j) ,
03806                 nifti_orientation_string(k)  ) ;
03807    }
03808 
03809    if( nim->sform_code > 0 ){
03810      int i,j,k ;
03811 
03812      sprintf( buf+strlen(buf) ,
03813               "  sform_code = '%d'\n"
03814               "  sform_code_name = '%s'\n"
03815      "  sto_xyz_matrix = '%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g'\n" ,
03816          nim->sform_code      , nifti_xform_string(nim->sform_code) ,
03817          nim->sto_xyz.m[0][0] , nim->sto_xyz.m[0][1] ,
03818          nim->sto_xyz.m[0][2] , nim->sto_xyz.m[0][3] ,
03819          nim->sto_xyz.m[1][0] , nim->sto_xyz.m[1][1] ,
03820          nim->sto_xyz.m[1][2] , nim->sto_xyz.m[1][3] ,
03821          nim->sto_xyz.m[2][0] , nim->sto_xyz.m[2][1] ,
03822          nim->sto_xyz.m[2][2] , nim->sto_xyz.m[2][3] ,
03823          nim->sto_xyz.m[3][0] , nim->sto_xyz.m[3][1] ,
03824          nim->sto_xyz.m[3][2] , nim->sto_xyz.m[3][3]  ) ;
03825 
03826      sprintf( buf+strlen(buf) ,
03827      "  sto_ijk matrix = '%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g'\n" ,
03828          nim->sto_ijk.m[0][0] , nim->sto_ijk.m[0][1] ,
03829          nim->sto_ijk.m[0][2] , nim->sto_ijk.m[0][3] ,
03830          nim->sto_ijk.m[1][0] , nim->sto_ijk.m[1][1] ,
03831          nim->sto_ijk.m[1][2] , nim->sto_ijk.m[1][3] ,
03832          nim->sto_ijk.m[2][0] , nim->sto_ijk.m[2][1] ,
03833          nim->sto_ijk.m[2][2] , nim->sto_ijk.m[2][3] ,
03834          nim->sto_ijk.m[3][0] , nim->sto_ijk.m[3][1] ,
03835          nim->sto_ijk.m[3][2] , nim->sto_ijk.m[3][3]  ) ;
03836 
03837      mat44_to_orientation( nim->sto_xyz , &i,&j,&k ) ;
03838      if( i > 0 && j > 0 && k > 0 )
03839        sprintf( buf+strlen(buf) ,
03840                 "  sform_i_orientation = '%s'\n"
03841                 "  sform_j_orientation = '%s'\n"
03842                 "  sform_k_orientation = '%s'\n" ,
03843                 nifti_orientation_string(i) ,
03844                 nifti_orientation_string(j) ,
03845                 nifti_orientation_string(k)  ) ;
03846    }
03847 
03848    sprintf( buf+strlen(buf) , "  num_ext = '%d'\n", nim->num_ext ) ;
03849 
03850    sprintf( buf+strlen(buf) , "/>\n" ) ;   /* XML-ish closer */
03851 
03852    nbuf = strlen(buf) ;
03853    buf  = (char *)realloc((void *)buf, nbuf+1); /* cut back to proper length */
03854    return buf ;
03855 }
03856 
03857 /*---------------------------------------------------------------------------*/
03858 
03859 int short_order(void)   /* determine this CPU's byte order */
03860 {
03861    union { unsigned char bb[2] ;
03862            short         ss    ; } fred ;
03863 
03864    fred.bb[0] = 1 ; fred.bb[1] = 0 ;
03865 
03866    return (fred.ss == 1) ? LSB_FIRST : MSB_FIRST ;
03867 }
03868 
03869 /*---------------------------------------------------------------------------*/
03870 
03871 #undef  QQNUM
03872 #undef  QNUM
03873 #undef  QSTR
03874 
03875 /* macro to check lhs string against "n1"; if it matches,
03876    interpret rhs string as a number, and put it into nim->"n2" */
03877 
03878 #define QQNUM(n1,n2) if( strcmp(lhs,#n1)==0 ) nim->n2=strtod(rhs,NULL)
03879 
03880 /* same, but where "n1" == "n2" */
03881 
03882 #define QNUM(nam)    QQNUM(nam,nam)
03883 
03884 /* macro to check lhs string against "nam"; if it matches,
03885    put rhs string into nim->"nam" string, with max length = "ml" */
03886 
03887 #define QSTR(nam,ml) if( strcmp(lhs,#nam) == 0 )                           \
03888                        strncpy(nim->nam,rhs,ml), nim->intent_name[ml]='\0'
03889 
03890 /*---------------------------------------------------------------------------*/
03891 /* Take an XML-ish ASCII string and create a NIFTI image header to match.
03892    NULL is returned if enough information isn't present in the input string.
03893     - The image data can later be loaded with nifti_image_load().
03894     - The struct returned here can be liberated with nifti_image_free().
03895     - Not a lot of error checking is done here to make sure that the
03896       input values are reasonable!
03897 -----------------------------------------------------------------------------*/
03898 
03899 nifti_image *nifti_image_from_ascii( char *str, int * bytes_read )
03900 {
03901    char lhs[1024] , rhs[1024] ;
03902    int ii , spos, nn , slen ;
03903    nifti_image *nim ;              /* will be output */
03904 
03905    if( str == NULL || *str == '\0' ) return NULL ;  /* bad input!? */
03906 
03907    /* scan for opening string */
03908 
03909    spos = 0 ; slen = strlen(str) ;
03910    ii = sscanf( str+spos , "%1023s%n" , lhs , &nn ) ; spos += nn ;
03911    if( ii == 0 || strcmp(lhs,"<nifti_image") != 0 ) return NULL ;
03912 
03913    /* create empty image struct */
03914 
03915    nim = (nifti_image *) calloc( 1 , sizeof(nifti_image) ) ;
03916 
03917    nim->nx = nim->ny = nim->nz = nim->nt
03918            = nim->nu = nim->nv = nim->nw = 1 ;
03919    nim->dx = nim->dy = nim->dz = nim->dt
03920            = nim->du = nim->dv = nim->dw = nim->qfac = 1.0 ;
03921 
03922    nim->byteorder = short_order() ;
03923 
03924    /* starting at str[spos], scan for "equations" of the form
03925          lhs = 'rhs'
03926       and assign rhs values into the struct component named by lhs */
03927 
03928    while(1){
03929 
03930      while( isspace(str[spos]) ) spos++ ;  /* skip whitespace */
03931      if( str[spos] == '\0' ) break ;       /* end of string? */
03932 
03933      /* get lhs string */
03934 
03935      ii = sscanf( str+spos , "%1023s%n" , lhs , &nn ) ; spos += nn ;
03936      if( ii == 0 || strcmp(lhs,"/>") == 0 ) break ;  /* end of input? */
03937 
03938      /* skip whitespace and the '=' marker */
03939 
03940      while( isspace(str[spos]) || str[spos] == '=' ) spos++ ;
03941      if( str[spos] == '\0' ) break ;       /* end of string? */
03942 
03943      /* if next character is a quote ', copy everything up to next '
03944         otherwise, copy everything up to next nonblank              */
03945 
03946      if( str[spos] == '\'' ){
03947         ii = spos+1 ;
03948         while( str[ii] != '\0' && str[ii] != '\'' ) ii++ ;
03949         nn = ii-spos-1 ; if( nn > 1023 ) nn = 1023 ;
03950         memcpy(rhs,str+spos+1,nn) ; rhs[nn] = '\0' ;
03951         spos = (str[ii] == '\'') ? ii+1 : ii ;
03952      } else {
03953         ii = sscanf( str+spos , "%1023s%n" , rhs , &nn ) ; spos += nn ;
03954         if( ii == 0 ) break ;  /* nothing found? */
03955      }
03956      unescape_string(rhs) ;  /* remove any XML escape sequences */
03957 
03958      /* Now can do the assignment, based on lhs string.
03959         Start with special cases that don't fit the QNUM/QSTR macros. */
03960 
03961      if( strcmp(lhs,"nifti_type") == 0 ){
03962             if( strcmp(rhs,"ANALYZE-7.5") == 0 ) nim->nifti_type = 0 ;
03963        else if( strcmp(rhs,"NIFTI-1+")    == 0 ) nim->nifti_type = 1 ;
03964        else if( strcmp(rhs,"NIFTI-1")     == 0 ) nim->nifti_type = 2 ;
03965        else if( strcmp(rhs,"NIFTI-1A")    == 0 ) nim->nifti_type = 3 ;
03966      }
03967      else if( strcmp(lhs,"header_filename") == 0 ){
03968        nim->fname = nifti_strdup(rhs) ;
03969      }
03970      else if( strcmp(lhs,"image_filename") == 0 ){
03971        nim->iname = nifti_strdup(rhs) ;
03972      }
03973      else if( strcmp(lhs,"sto_xyz_matrix") == 0 ){
03974        sscanf( rhs , "%f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f" ,
03975                &(nim->sto_xyz.m[0][0]) , &(nim->sto_xyz.m[0][1]) ,
03976                &(nim->sto_xyz.m[0][2]) , &(nim->sto_xyz.m[0][3]) ,
03977                &(nim->sto_xyz.m[1][0]) , &(nim->sto_xyz.m[1][1]) ,
03978                &(nim->sto_xyz.m[1][2]) , &(nim->sto_xyz.m[1][3]) ,
03979                &(nim->sto_xyz.m[2][0]) , &(nim->sto_xyz.m[2][1]) ,
03980                &(nim->sto_xyz.m[2][2]) , &(nim->sto_xyz.m[2][3]) ,
03981                &(nim->sto_xyz.m[3][0]) , &(nim->sto_xyz.m[3][1]) ,
03982                &(nim->sto_xyz.m[3][2]) , &(nim->sto_xyz.m[3][3])  ) ;
03983      }
03984      else if( strcmp(lhs,"byteorder") == 0 ){
03985        if( strcmp(rhs,"MSB_FIRST") == 0 ) nim->byteorder = MSB_FIRST ;
03986        if( strcmp(rhs,"LSB_FIRST") == 0 ) nim->byteorder = LSB_FIRST ;
03987      }
03988      else QQNUM(image_offset,iname_offset) ;
03989      else QNUM(datatype) ;
03990      else QNUM(ndim) ;
03991      else QNUM(nx) ;
03992      else QNUM(ny) ;
03993      else QNUM(nz) ;
03994      else QNUM(nt) ;
03995      else QNUM(nu) ;
03996      else QNUM(nv) ;
03997      else QNUM(nw) ;
03998      else QNUM(dx) ;
03999      else QNUM(dy) ;
04000      else QNUM(dz) ;
04001      else QNUM(dt) ;
04002      else QNUM(du) ;
04003      else QNUM(dv) ;
04004      else QNUM(dw) ;
04005      else QNUM(cal_min) ;
04006      else QNUM(cal_max) ;
04007      else QNUM(scl_slope) ;
04008      else QNUM(scl_inter) ;
04009      else QNUM(intent_code) ;
04010      else QNUM(intent_p1) ;
04011      else QNUM(intent_p2) ;
04012      else QNUM(intent_p3) ;
04013      else QSTR(intent_name,15) ;
04014      else QNUM(toffset) ;
04015      else QNUM(xyz_units) ;
04016      else QNUM(time_units) ;
04017      else QSTR(descrip,79) ;
04018      else QSTR(aux_file,23) ;
04019      else QNUM(qform_code) ;
04020      else QNUM(quatern_b) ;
04021      else QNUM(quatern_c) ;
04022      else QNUM(quatern_d) ;
04023      else QNUM(qoffset_x) ;
04024      else QNUM(qoffset_y) ;
04025      else QNUM(qoffset_z) ;
04026      else QNUM(qfac) ;
04027      else QNUM(sform_code) ;
04028      else QNUM(freq_dim) ;
04029      else QNUM(phase_dim) ;
04030      else QNUM(slice_dim) ;
04031      else QNUM(slice_code) ;
04032      else QNUM(slice_start) ;
04033      else QNUM(slice_end) ;
04034      else QNUM(slice_duration) ;
04035      else QNUM(num_ext) ;
04036 
04037    } /* end of while loop */
04038 
04039    if( bytes_read ) *bytes_read = spos+1;         /* "process" last '\n' */
04040 
04041    /** do miscellaneous checking and cleanup **/
04042 
04043    if( nim->ndim <= 0 ){ nifti_image_free(nim); return NULL; } /** bad! **/
04044 
04045    nifti_datatype_sizes( nim->datatype, &(nim->nbyper), &(nim->swapsize) );
04046    if( nim->nbyper == 0 ){ nifti_image_free(nim); return NULL; } /** bad! **/
04047 
04048    nim->dim[0] = nim->ndim ;
04049    nim->dim[1] = nim->nx ; nim->pixdim[1] = nim->dx ;
04050    nim->dim[2] = nim->ny ; nim->pixdim[2] = nim->dy ;
04051    nim->dim[3] = nim->nz ; nim->pixdim[3] = nim->dz ;
04052    nim->dim[4] = nim->nt ; nim->pixdim[4] = nim->dt ;
04053    nim->dim[5] = nim->nu ; nim->pixdim[5] = nim->du ;
04054    nim->dim[6] = nim->nv ; nim->pixdim[6] = nim->dv ;
04055    nim->dim[7] = nim->nw ; nim->pixdim[7] = nim->dw ;
04056 
04057    nim->nvox =  nim->nx * nim->ny * nim->nz
04058               * nim->nt * nim->nu * nim->nv * nim->nw ;
04059 
04060    if( nim->qform_code > 0 )
04061      nim->qto_xyz = quatern_to_mat44(
04062                       nim->quatern_b, nim->quatern_c, nim->quatern_d,
04063                       nim->qoffset_x, nim->qoffset_y, nim->qoffset_z,
04064                       nim->dx       , nim->dy       , nim->dz       ,
04065                       nim->qfac                                      ) ;
04066    else
04067      nim->qto_xyz = quatern_to_mat44(
04068                       0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 ,
04069                       nim->dx , nim->dy , nim->dz , 0.0 ) ;
04070 
04071 
04072    nim->qto_ijk = mat44_inverse( nim->qto_xyz ) ;
04073 
04074    if( nim->sform_code > 0 )
04075      nim->sto_ijk = mat44_inverse( nim->sto_xyz ) ;
04076 
04077    return nim ;
04078 }
Powered by Plone

This site conforms to the following standards: