nifti2_data_format > NIfTI-2: a 64-bit update of NIfTI1 (approved)
Mar 15, 2011  10:03 AM
NIfTI-2: a 64-bit update of NIfTI1 (approved)
A 64-bit update to the NIfTI format (approved by the NIFTI Data Format Working Group on March 16, 2011)

The NIfTI committee, in conjunction with public discussion on the NITRC forum, have created a final version for the NIfTI-2 format that is a very simple extension of the current NIfTI-1 format, but updated to allow 64-bit storage and addressing for large images and matrices.  

It is intended that this format:
 - will enable the storage of large images and matrices, with all dimensions being coded by 64-bit integers rather than the current limitation of 16-bit signed integers (which currently gives a restrictive 32767 size limit in each dimension)
 - will be very simple to implement and update software (a couple of hours coding or less generally)
 - contains the same information and logic as a NIfTI-1 file (no new fields and all current fields still retained)
 - will support the existing file formats and naming: a .nii single-file, a .hdr/.img file-pair and their gzipped versions
 - has a very simple test (see below) to determine if the file is NIfTI-1 or NIfTI-2
 - does not replace NIfTI-1 in the short term but is supported alongside it

Comments
This revised version is the result of initial committee discussions and public discussion on the NITRC forum.In addition to this format, we are seeking comments relating to larger-scale changes and requests for other types of format change be posted to a separate NITRC discussion list for more advanced neuroimaging formats (www.nitrc.org/forum/forum.php?forum_id=1942)

Supporting software
 - AFNI, BrainVisa, BrainVoyager, Caret, Connectome Workbench, Fiswidgets, FreeSurfer, FSL, ITK, LONI-DIRAC, Mango, MRIcron, NiBabel, R, SPM and TractoR have all agreed to support the NIfTI-2 version in their upcoming releases, but that NIfTI-1 will remain a default output, or a configurable default, in the short-term
 - the sourceforge supporting libraries in niftilib will be updated so that they seemlessly support both NIfTI-1 and NIfTI-2
 - conversion utilities to and from NIfTI-1 will be made available via sourceforge as well as in some of the software packages mentioned above

Changes to the header
The changes to the NIfTI header structure are the following (also see below for the full header struct):
   - short dim[8] becomes int64_t dim[8]
   - float intent_p1 becomes double intent_p1
   - float intent_p2 becomes double intent_p2
   - float intent_p3 becomes double intent_p3
   - float pixdim[8] becomes double pixdim[8]
   - float vox_offset becomes int64_t vox_offset
   - float scl_slope becomes double scl_slope
   - float scl_inter becomes double scl_inter
   - float cal_max becomes double cal_max
   - float cal_min becomes double cal_min
   - float slice_duration becomes double slice_duration
   - float toffset becomes double toffset
   - short slice_start becomes int64_t slice_start
   - short slice_end becomes int64_t slice_end
   - char slice_code becomes int slice_code
   - char xyzt_units becomes int xyzt_units
   - short intent_code becomes int intent_code
   - short qform_code becomes int qform_code
   - short sform_code becomes int sform_code
   - float quatern_b becomes double quatern_b
        and similarly for quatern_c, quatern_d, qoffset_x, qoffset_y, qoffset_z
   - float srow_x[4] becomes double srow_x[4]
        and similarly for srow_y[4], srow_z[4]
   - char magic[4] becomes char magic[8]
   - char unused_str[15] is added at the end of the header   
   - removing previously unused fields: data_type, db_name, extents, session_error, regular, glmax, glmin  
   - reordering of some of the fields to ensure 8-byte alignments for all doubles 
The size and type of all other fields remains unchanged.
The sizeof_hdr must store 540 for a NIfTI-2 file instead of 348 for NIfTI-1.
Extension information is still held in the first 4 bytes after this header (bytes 541-544) in the same way as in NIfTI-1.
Note that the total block size of 544 (header + 4 bytes) retains the 16-byte alignment in NIfTI-1 (348+4=352), as needed for convenient memory-mapping.
The changes of float to double are generally made to allow for more accurate mapping of intensities or indices when dealing with very large arrays, and unused_str is added to ensure the 16-byte alignment holds. The 8-byte alignment of doubles is important of some platforms and necessitated shifting of several smaller fields.
In addition, a range of custom codes for NIFTI_INTENT_*, NIFTI_XFORM_*, NIFTI_UNITS_* and NIFTI_SLICE_* will be created, although these are intended for temporary use only and users are encouraged to register any codes that are useful in the long-term with the NIfTI committee in order for them to become usable by all and keep NIfTI an open standard without private or hidden information.

Compatibility
This format is not, and cannot be, bit-wise compatible with the previous NIfTI-1 (or ANALYZE) formats and so will not work with existing NIfTI-1 software directly. In the short term this can be solved via conversion utilities. A NIfTI-2 image will not be recognised as a valid NIfTI-1 image by existing software and so no incorrect processing or analyses should occur. In the longer term most code should be very easily converted to work with both NIfTI-2 and NIfTI-1 by using the updated sourceforge libraries or making equivalent changes internally.  The change in format is intentionally very minimal and should be very easy to code.

Determining the NIfTI version
The following pseudo-code shows one way that a file can be tested to see: (a) if it is a NIfTI image file, (b) what version of NIfTI it is, and (c) whether byte-swapping is required.

read in the first 4 bytes from the file
let d = the content of these bytes, formatted as a 32-bit int
if (d==348) then it is a NIfTI-1 file, no byte-swapping required
else if (swap_4bytes(d)==348) then it is a NIfTI-1 file, but with byte-swapping required
else if (d==540) then it is a NIfTI-2 file, no byte-swapping required
else if (swap_4bytes(d)==540) then it is a NIfTI-2 file, but with byte-swapping required
else it is not a valid NIfTI file
read in magic[] string from appropriate place (depending on if it is NIfTI-1 or NIfTI-2)
check validity of the NIfTI file by testing the magic[] string (should contain "ni1" or "n+1" followed by \0 for NIfTI-1, and "ni2" or "n+2" followed by \0 and 4 extra signature bytes for NIfTI-2)

if it passed the above tests then read in the full header into the appropriate NIfTI-1 or NIfTI-2 struct

 
Magic Signature
The magic string is expanded to 8 bytes with the first 4 bytes containing ones of the strings "ni2" or "n+2", terminated with \0.  The next four bytes form a magic signature much the same as used by the PNG format (http://www.libpng.org/pub/png/pngintro.html), to detect for file transfer errors involving newline characters.  The extra four bytes are the same as the last four in the PNG format - that is: \r \n \032 \n (0D 0A 1A 0A)
The magic string has a different offset from the start of the file in NIfTI-1 and NIfTI-2 (344 and 4 bytes respectively).

Timeline
Barring any unknown unknowns or unforseeable unforseen problems, it is intended to begin rolling out this format in practice in March-April 2011.  Example datasets and updated code will also be provided soon.
 
C Header Struct
/*! \struct nifti_2_header
    \brief Data structure defining the fields in the nifti2 header.
           This binary header should be found at the beginning of a valid
           NIFTI-2 header file.
 */
                        /*************************/  /************************/ /************/
struct nifti_2_header { /* NIFTI-2 usage         */  /* NIFTI-1 usage        */ /*  offset  */
                        /*************************/  /************************/ /************/
int   sizeof_hdr;     /*!< MUST be 540           */  /* int sizeof_hdr; (348) */  /*   0 */
char  magic[8] ;      /*!< MUST be valid signature. */  /* char magic[4];     */  /*   4 */
short datatype;       /*!< Defines data type!    */  /* short datatype;       */  /*  12 */
short bitpix;         /*!< Number bits/voxel.    */  /* short bitpix;         */  /*  14 */
int64_t dim[8];       /*!< Data array dimensions.*/  /* short dim[8];         */  /*  16 */
double intent_p1 ;    /*!< 1st intent parameter. */  /* float intent_p1;      */  /*  80 */
double intent_p2 ;    /*!< 2nd intent parameter. */  /* float intent_p2;      */  /*  88 */
double intent_p3 ;    /*!< 3rd intent parameter. */  /* float intent_p3;      */  /*  96 */
double pixdim[8];     /*!< Grid spacings.        */  /* float pixdim[8];      */  /* 104 */
int64_t vox_offset;   /*!< Offset into .nii file */  /* float vox_offset;     */  /* 168 */
double scl_slope ;    /*!< Data scaling: slope.  */  /* float scl_slope;      */  /* 176 */
double scl_inter ;    /*!< Data scaling: offset. */  /* float scl_inter;      */  /* 184 */
double cal_max;       /*!< Max display intensity */  /* float cal_max;        */  /* 192 */
double cal_min;       /*!< Min display intensity */  /* float cal_min;        */  /* 200 */
double slice_duration;/*!< Time for 1 slice.     */  /* float slice_duration; */  /* 208 */
double toffset;       /*!< Time axis shift.      */  /* float toffset;        */  /* 216 */
int64_t slice_start;  /*!< First slice index.    */  /* short slice_start;    */  /* 224 */
int64_t slice_end;    /*!< Last slice index.     */  /* short slice_end;      */  /* 232 */
char  descrip[80];    /*!< any text you like.    */  /* char descrip[80];     */  /* 240 */
char  aux_file[24];   /*!< auxiliary filename.   */  /* char aux_file[24];    */  /* 320 */
int qform_code ;      /*!< NIFTI_XFORM_* code.   */ /* short qform_code;      */  /* 344 */
int sform_code ;      /*!< NIFTI_XFORM_* code.   */ /* short sform_code;      */  /* 348 */
double quatern_b ;    /*!< Quaternion b param.   */ /* float quatern_b;       */  /* 352 */
double quatern_c ;    /*!< Quaternion c param.   */ /* float quatern_c;       */  /* 360 */
double quatern_d ;    /*!< Quaternion d param.   */ /* float quatern_d;       */  /* 368 */
double qoffset_x ;    /*!< Quaternion x shift.   */ /* float qoffset_x;       */  /* 376 */
double qoffset_y ;    /*!< Quaternion y shift.   */ /* float qoffset_y;       */  /* 384 */
double qoffset_z ;    /*!< Quaternion z shift.   */ /* float qoffset_z;       */  /* 392 */
double srow_x[4] ;    /*!< 1st row affine transform. */  /* float srow_x[4];  */  /* 400 */
double srow_y[4] ;    /*!< 2nd row affine transform. */  /* float srow_y[4];  */  /* 432 */
double srow_z[4] ;    /*!< 3rd row affine transform. */  /* float srow_z[4];  */  /* 464 */
int slice_code ;      /*!< Slice timing order.   */  /* char slice_code;      */  /* 496 */
int xyzt_units ;      /*!< Units of pixdim[1..4] */  /* char xyzt_units;      */  /* 500 */
int intent_code ;     /*!< NIFTI_INTENT_* code.  */  /* short intent_code;    */  /* 504 */
char intent_name[16]; /*!< 'name' or meaning of data. */ /* char intent_name[16]; */  /* 508 */
char dim_info;        /*!< MRI slice ordering.   */      /* char dim_info;        */  /* 524 */
char unused_str[15];  /*!< unused, filled with \0 */                                  /* 525 */
} ;                   /**** 540 bytes total ****/
typedef struct nifti_2_header nifti_2_header ;
 
[b][b][b][b][b][b] [/b][/b][/b][/b][/b][/b]
reply reply with quote
Threaded View
TitleAuthorDate
NIfTI-2: a 64-bit update of NIfTI1 (approved)Mark JenkinsonMar 15, 2011
      RE: 64-bit update to the NIfTI formatCinly OoiMar 15, 2011
            RE: 64-bit update to the NIfTI formatMark JenkinsonMar 16, 2011
                  RE: 64-bit update to the NIfTI formatCinly OoiMar 17, 2011
            RE: 64-bit update to the NIfTI formatCinly OoiMar 16, 2011
            RE: 64-bit update to the NIfTI formatCinly OoiMar 15, 2011