NIFTI_20090325/extra_nii_hdr.m
87b08fd7
 %  Decode extra NIFTI header information into hdr.extra
 %
 %  Usage: hdr = extra_nii_hdr(hdr)
 %
 %  hdr can be obtained from load_nii_hdr
 %
 %  NIFTI data format can be found on: http://nifti.nimh.nih.gov
 %
 %  - Jimmy Shen (jimmy@rotman-baycrest.on.ca)
 %
 function hdr = extra_nii_hdr(hdr)
 
    switch hdr.dime.datatype
    case 1
       extra.NIFTI_DATATYPES = 'DT_BINARY';
    case 2
       extra.NIFTI_DATATYPES = 'DT_UINT8';
    case 4
       extra.NIFTI_DATATYPES = 'DT_INT16';
    case 8
       extra.NIFTI_DATATYPES = 'DT_INT32';
    case 16
       extra.NIFTI_DATATYPES = 'DT_FLOAT32';
    case 32
       extra.NIFTI_DATATYPES = 'DT_COMPLEX64';
    case 64
       extra.NIFTI_DATATYPES = 'DT_FLOAT64';
    case 128
       extra.NIFTI_DATATYPES = 'DT_RGB24';
    case 256
       extra.NIFTI_DATATYPES = 'DT_INT8';
    case 512
       extra.NIFTI_DATATYPES = 'DT_UINT16';
    case 768
       extra.NIFTI_DATATYPES = 'DT_UINT32';
    case 1024
       extra.NIFTI_DATATYPES = 'DT_INT64';
    case 1280
       extra.NIFTI_DATATYPES = 'DT_UINT64';
    case 1536
       extra.NIFTI_DATATYPES = 'DT_FLOAT128';
    case 1792
       extra.NIFTI_DATATYPES = 'DT_COMPLEX128';
    case 2048
       extra.NIFTI_DATATYPES = 'DT_COMPLEX256';
    otherwise
       extra.NIFTI_DATATYPES = 'DT_UNKNOWN';
    end
 
    switch hdr.dime.intent_code
    case 2
       extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_CORREL';
    case 3
       extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_TTEST';
    case 4
       extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_FTEST';
    case 5
       extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_ZSCORE';
    case 6
       extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_CHISQ';
    case 7
       extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_BETA';
    case 8
       extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_BINOM';
    case 9
       extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_GAMMA';
    case 10
       extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_POISSON';
    case 11
       extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_NORMAL';
    case 12
       extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_FTEST_NONC';
    case 13
       extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_CHISQ_NONC';
    case 14
       extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_LOGISTIC';
    case 15
       extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_LAPLACE';
    case 16
       extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_UNIFORM';
    case 17
       extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_TTEST_NONC';
    case 18
       extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_WEIBULL';
    case 19
       extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_CHI';
    case 20
       extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_INVGAUSS';
    case 21
       extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_EXTVAL';
    case 22
       extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_PVAL';
    case 23
       extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_LOGPVAL';
    case 24
       extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_LOG10PVAL';
    case 1001
       extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_ESTIMATE';
    case 1002
       extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_LABEL';
    case 1003
       extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_NEURONAME';
    case 1004
       extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_GENMATRIX';
    case 1005
       extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_SYMMATRIX';
    case 1006
       extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_DISPVECT';
    case 1007
       extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_VECTOR';
    case 1008
       extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_POINTSET';
    case 1009
       extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_TRIANGLE';
    case 1010
       extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_QUATERNION';
    case 1011
       extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_DIMLESS';
    otherwise
       extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_NONE';
    end
 
    extra.NIFTI_INTENT_NAMES = hdr.hist.intent_name;
 
    if hdr.hist.sform_code > 0
       switch hdr.hist.sform_code
       case 1
          extra.NIFTI_SFORM_CODES = 'NIFTI_XFORM_SCANNER_ANAT';
       case 2
          extra.NIFTI_SFORM_CODES = 'NIFTI_XFORM_ALIGNED_ANAT';
       case 3
          extra.NIFTI_SFORM_CODES = 'NIFTI_XFORM_TALAIRACH';
       case 4
          extra.NIFTI_SFORM_CODES = 'NIFTI_XFORM_MNI_152';
       otherwise
          extra.NIFTI_SFORM_CODES = 'NIFTI_XFORM_UNKNOWN';
       end
 
       extra.NIFTI_QFORM_CODES = 'NIFTI_XFORM_UNKNOWN';
    elseif hdr.hist.qform_code > 0
       extra.NIFTI_SFORM_CODES = 'NIFTI_XFORM_UNKNOWN';
 
       switch hdr.hist.qform_code
       case 1
          extra.NIFTI_QFORM_CODES = 'NIFTI_XFORM_SCANNER_ANAT';
       case 2
          extra.NIFTI_QFORM_CODES = 'NIFTI_XFORM_ALIGNED_ANAT';
       case 3
          extra.NIFTI_QFORM_CODES = 'NIFTI_XFORM_TALAIRACH';
       case 4
          extra.NIFTI_QFORM_CODES = 'NIFTI_XFORM_MNI_152';
       otherwise
          extra.NIFTI_QFORM_CODES = 'NIFTI_XFORM_UNKNOWN';
       end
    else
       extra.NIFTI_SFORM_CODES = 'NIFTI_XFORM_UNKNOWN';
       extra.NIFTI_QFORM_CODES = 'NIFTI_XFORM_UNKNOWN';
    end
 
    switch bitand(hdr.dime.xyzt_units, 7)	% mask with 0x07
    case 1
       extra.NIFTI_SPACE_UNIT = 'NIFTI_UNITS_METER';
    case 2
       extra.NIFTI_SPACE_UNIT = 'NIFTI_UNITS_MM';	% millimeter
    case 3
       extra.NIFTI_SPACE_UNIT = 'NIFTI_UNITS_MICRO';
    otherwise
       extra.NIFTI_SPACE_UNIT = 'NIFTI_UNITS_UNKNOWN';
    end
 
    switch bitand(hdr.dime.xyzt_units, 56)	% mask with 0x38
    case 8
       extra.NIFTI_TIME_UNIT = 'NIFTI_UNITS_SEC';
    case 16
       extra.NIFTI_TIME_UNIT = 'NIFTI_UNITS_MSEC';
    case 24
       extra.NIFTI_TIME_UNIT = 'NIFTI_UNITS_USEC';	% microsecond
    otherwise
       extra.NIFTI_TIME_UNIT = 'NIFTI_UNITS_UNKNOWN';
    end
 
    switch hdr.dime.xyzt_units
    case 32
       extra.NIFTI_SPECTRAL_UNIT = 'NIFTI_UNITS_HZ';
    case 40
       extra.NIFTI_SPECTRAL_UNIT = 'NIFTI_UNITS_PPM';	% part per million
    case 48
       extra.NIFTI_SPECTRAL_UNIT = 'NIFTI_UNITS_RADS';	% radians per second
    otherwise
       extra.NIFTI_SPECTRAL_UNIT = 'NIFTI_UNITS_UNKNOWN';
    end
 
    %  MRI-specific spatial and temporal information
    %
    dim_info = hdr.hk.dim_info;
    extra.NIFTI_FREQ_DIM = bitand(dim_info, 3);
    extra.NIFTI_PHASE_DIM = bitand(bitshift(dim_info, -2), 3);
    extra.NIFTI_SLICE_DIM = bitand(bitshift(dim_info, -4), 3);
 
    %  Check slice code
    %
    switch hdr.dime.slice_code
    case 1
       extra.NIFTI_SLICE_ORDER = 'NIFTI_SLICE_SEQ_INC';	% sequential increasing
    case 2
       extra.NIFTI_SLICE_ORDER = 'NIFTI_SLICE_SEQ_DEC';	% sequential decreasing
    case 3
       extra.NIFTI_SLICE_ORDER = 'NIFTI_SLICE_ALT_INC';	% alternating increasing
    case 4
       extra.NIFTI_SLICE_ORDER = 'NIFTI_SLICE_ALT_DEC';	% alternating decreasing
    case 5
       extra.NIFTI_SLICE_ORDER = 'NIFTI_SLICE_ALT_INC2';	% ALT_INC # 2
    case 6
       extra.NIFTI_SLICE_ORDER = 'NIFTI_SLICE_ALT_DEC2';	% ALT_DEC # 2
    otherwise
       extra.NIFTI_SLICE_ORDER = 'NIFTI_SLICE_UNKNOWN';
    end
 
    %  Check NIFTI version
    %
    if     ~isempty(hdr.hist.magic) & strcmp(hdr.hist.magic(1),'n') & ...
 	( strcmp(hdr.hist.magic(2),'i') | strcmp(hdr.hist.magic(2),'+') ) & ...
 	  str2num(hdr.hist.magic(3)) >= 1 & str2num(hdr.hist.magic(3)) <= 9
 
       extra.NIFTI_VERSION = str2num(hdr.hist.magic(3));
    else
       extra.NIFTI_VERSION = 0;
    end
 
    %  Check if data stored in the same file (*.nii) or separate
    %  files (*.hdr/*.img)
    %
    if isempty(hdr.hist.magic)
       extra.NIFTI_ONEFILE = 0;
    else
       extra.NIFTI_ONEFILE = strcmp(hdr.hist.magic(2), '+');
    end
 
    %  Swap has been taken care of by checking whether sizeof_hdr is
    %  348 (machine is 'ieee-le' or 'ieee-be' etc)
    %
    % extra.NIFTI_NEEDS_SWAP = (hdr.dime.dim(1) < 0 | hdr.dime.dim(1) > 7);
 
    %  Check NIFTI header struct contains a 5th (vector) dimension
    %
    if hdr.dime.dim(1) > 4 & hdr.dime.dim(6) > 1
       extra.NIFTI_5TH_DIM = hdr.dime.dim(6);
    else
       extra.NIFTI_5TH_DIM = 0;
    end
 
    hdr.extra = extra;
 
    return;					% extra_nii_hdr