/vol/vipdata/irtk/image++/include/irtkNIFTI.h

00001 /*=========================================================================
00002 
00003   Library   : Image Registration Toolkit (IRTK)
00004   Module    : $Id: irtkNIFTI.h 8 2009-03-02 16:12:58Z dr $
00005   Copyright : Imperial College, Department of Computing
00006               Visual Information Processing (VIP), 2008 onwards
00007   Date      : $Date: 2009-03-02 16:12:58 +0000 (Mon, 02 Mar 2009) $
00008   Version   : $Revision: 8 $
00009   Changes   : $Author: dr $
00010 
00011 =========================================================================*/
00012 
00013 #ifndef _IRTKNIFTI_H
00014 
00015 #define _IRTKNIFTI_H
00016 
00017 #ifdef HAS_NIFTI
00018 
00019 #include <nifti1_io.h>
00020 
00021 #define NIFTI_RADIOLOGICAL        -1
00022 #define NIFTI_NEUROLOGICAL         1
00023 #define NIFTI_INCONSISTENT         0
00024 
00030 class irtkNIFTIHeader
00031 {
00032 
00033 public:
00034 
00036   nifti_image *nim;
00037 
00039   irtkNIFTIHeader();
00040 
00042   ~irtkNIFTIHeader();
00043 
00045   void Read(const char *);
00046 
00047   // Initialize header with minimal set of fields and orientation info.
00048   void Initialize(int, int, int, int, double, double, double, double, int, irtkMatrix &i2w);
00049 
00051   void Print();
00052 
00053 };
00054 
00055 inline irtkNIFTIHeader::irtkNIFTIHeader()
00056 {
00057   nim = nifti_simple_init_nim();
00058 }
00059 
00060 inline irtkNIFTIHeader::~irtkNIFTIHeader()
00061 {
00062   if (nim != NULL) {
00063     nim->data = NULL; // (de)allocated elsewhere
00064     nifti_image_free(nim);
00065   }
00066   nim = NULL;
00067 }
00068 
00069 inline void irtkNIFTIHeader::Read(const char *filename)
00070 {
00071   // Be good
00072   if (nim != NULL) nifti_image_free(nim);
00073 
00074   // Use nifti1_io to read header (not data)
00075   int read_data = 0;
00076   nim = nifti_image_read(filename, read_data);
00077 
00078 #ifdef HAS_DEBUG
00079   // Just checking
00080   this->Print();
00081 #endif
00082 }
00083 
00084 inline void irtkNIFTIHeader::Initialize(int x, int y, int z, int t,
00085                                         double xsize, double ysize, double zsize, double tsize,
00086                                         int datatype,
00087                                         irtkMatrix &i2w)
00088 {
00089   int nbytepix = 0, ss = 0;
00090   int i, j;
00091 
00092   // Copy passed fields
00093   nim->datatype = datatype; // Will be NIFTI_TYPE_UINT8 | NIFTI_TYPE_INT16 | NIFTI_TYPE_FLOAT32
00094   nim->nx = x;
00095   nim->ny = y;
00096   nim->nz = z;
00097   nim->dx = fabs(xsize);   // Store only absolute pixel size values
00098   nim->dy = fabs(ysize);   // dito
00099   nim->dz = fabs(zsize);   // ...
00100   // Redundant fields ndim->dim/pixdim will be filled by nim2nhdr/nhdr2nim conversions in Write()
00101 
00102   // Default values for 3D
00103   if (t == 0) {
00104     nim->nifti_type = 1;     // 1==NIFTI-1 (1 file) - should set the magic in nhdr in Write()
00105     nim->ndim = 3;
00106     nim->nt   = 1;           // So that nvox can be computed correctly, see below
00107     nim->nu   = 1;           // dito
00108     nim->nv   = 1;           // ...
00109     nim->nw   = 1;           // ...
00110     nim->dt   = 1;           // or 0???
00111   } else {
00112     nim->nifti_type = 1;     // 1==NIFTI-1 (1 file) - should set the magic in nhdr in Write()
00113     nim->ndim = 4;
00114     nim->nt   = t;           // So that nvox can be computed correctly, see below
00115     nim->nu   = 1;           // dito
00116     nim->nv   = 1;           // ...
00117     nim->nw   = 1;           // ...
00118     nim->dt   = fabs(tsize);
00119   }
00120 
00121   // Derived values
00122   nifti_datatype_sizes(datatype, &nbytepix, &ss);
00123   nim->nbyper = nbytepix;
00124   nim->nvox   = nim->nx * nim->ny * nim->nz * nim->nt * nim->nu * nim->nv * nim->nw;
00125 
00126   // Compute qform
00127   mat44 mat_44;
00128 
00129   for (i = 0; i < 4; ++i) {
00130     for (j = 0; j < 4; ++j) {
00131       mat_44.m[i][j] = i2w(i, j);
00132     }
00133   }
00134 
00135   nim->qform_code = 1;
00136   nim->qto_xyz = mat_44;
00137   nifti_mat44_to_quatern(
00138     mat_44,
00139     &(nim->quatern_b), &(nim->quatern_c), &(nim->quatern_d),
00140     &(nim->qoffset_x), &(nim->qoffset_y), &(nim->qoffset_z),
00141     &(nim->dx)       , &(nim->dy)       , &(nim->dz)       ,
00142     &(nim->qfac));
00143 
00144   // Don't use sform
00145   nim->sform_code = 0;
00146 
00147   // Set the units to mm and seconds
00148   nim->xyz_units  = NIFTI_UNITS_MM;
00149   nim->time_units = NIFTI_UNITS_SEC;
00150   nim->toffset = 0;
00151 
00152   // Other stuff I could think of:
00153   nim->scl_slope = 1;
00154   nim->scl_inter = 0;
00155   nim->intent_code = 0;
00156   nim->intent_p1 = nim->intent_p2 = nim->intent_p3 = 0;
00157 
00158   // Data will be written out by ImageToFile class
00159   nim->data = NULL;
00160 }
00161 
00162 inline void irtkNIFTIHeader::Print()
00163 {
00164   cerr << "irtkNIFTIHeader::Print() : \n";
00165   if (nim != NULL) nifti_image_infodump(nim);
00166 }
00167 
00168 
00169 #endif
00170 
00171 #endif