Save NIFTI dataset header. Support both *.nii and *.hdr/*.img file extension. Usage: save_nii_ana_hdr_cbi(hdr, fid) hdr - struct with NIFTI header fields. fileprefix - NIFTI file name without extension. Part of this file is copied and modified under GNU license from MRI_TOOLBOX developed by CNSP in Flinders University, Australia NIFTI data format can be found on: http://nifti.nimh.nih.gov - Jimmy Shen (pls@rotman-baycrest.on.ca)
0001 function save_nii_ana_hdr_cbi(hdr, fid) 0002 % Save NIFTI dataset header. Support both *.nii and *.hdr/*.img file 0003 % extension. 0004 % 0005 % Usage: save_nii_ana_hdr_cbi(hdr, fid) 0006 % 0007 % hdr - struct with NIFTI header fields. 0008 % 0009 % fileprefix - NIFTI file name without extension. 0010 % 0011 % Part of this file is copied and modified under GNU license from 0012 % MRI_TOOLBOX developed by CNSP in Flinders University, Australia 0013 % 0014 % NIFTI data format can be found on: http://nifti.nimh.nih.gov 0015 % 0016 % - Jimmy Shen (pls@rotman-baycrest.on.ca) 0017 % 0018 0019 if ~exist('hdr','var') | ~exist('fid','var') 0020 error('Usage: save_nii_ana_hdr_cbi(hdr, fid)'); 0021 end 0022 0023 if ~isequal(hdr.hk.sizeof_hdr,348), 0024 error('hdr.hk.sizeof_hdr must be 348.'); 0025 end 0026 0027 % if hdr.hist.qform_code == 0 & hdr.hist.sform_code == 0 0028 % hdr.hist.sform_code = 1; 0029 % hdr.hist.srow_x(1) = hdr.dime.pixdim(2); 0030 % hdr.hist.srow_x(2) = 0; 0031 % hdr.hist.srow_x(3) = 0; 0032 % hdr.hist.srow_y(1) = 0; 0033 % hdr.hist.srow_y(2) = hdr.dime.pixdim(3); 0034 % hdr.hist.srow_y(3) = 0; 0035 % hdr.hist.srow_z(1) = 0; 0036 % hdr.hist.srow_z(2) = 0; 0037 % hdr.hist.srow_z(3) = hdr.dime.pixdim(4); 0038 % hdr.hist.srow_x(4) = (1-hdr.hist.originator(1))*hdr.dime.pixdim(2); 0039 % hdr.hist.srow_y(4) = (1-hdr.hist.originator(2))*hdr.dime.pixdim(3); 0040 % hdr.hist.srow_z(4) = (1-hdr.hist.originator(3))*hdr.dime.pixdim(4); 0041 % end 0042 0043 write_header(hdr, fid); 0044 0045 return; % save_nii_ana_hdr_cbi 0046 0047 0048 %--------------------------------------------------------------------- 0049 function write_header(hdr, fid) 0050 0051 % Original header structures 0052 % struct dsr /* dsr = hdr */ 0053 % { 0054 % struct header_key hk; /* 0 + 40 */ 0055 % struct image_dimension dime; /* 40 + 108 */ 0056 % struct data_history hist; /* 148 + 200 */ 0057 % }; /* total= 348 bytes*/ 0058 0059 header_key(fid, hdr.hk); 0060 image_dimension(fid, hdr.dime); 0061 data_history(fid, hdr.hist); 0062 0063 % check the file size is 348 bytes 0064 % 0065 fbytes = ftell(fid); 0066 0067 if ~isequal(fbytes,348), 0068 msg = sprintf('Header size is not 348 bytes.'); 0069 warning(msg); 0070 end 0071 0072 return; % write_header 0073 0074 0075 %--------------------------------------------------------------------- 0076 function header_key(fid, hk) 0077 0078 fseek(fid,0,'bof'); 0079 0080 % Original header structures 0081 % struct header_key /* header key */ 0082 % { /* off + size */ 0083 % int sizeof_hdr /* 0 + 4 */ 0084 % char data_type[10]; /* 4 + 10 */ 0085 % char db_name[18]; /* 14 + 18 */ 0086 % int extents; /* 32 + 4 */ 0087 % short int session_error; /* 36 + 2 */ 0088 % char regular; /* 38 + 1 */ 0089 % char dim_info; % char hkey_un0; /* 39 + 1 */ 0090 % }; /* total=40 bytes */ 0091 0092 fwrite(fid, hk.sizeof_hdr(1), 'int32'); % must be 348. 0093 0094 % data_type = sprintf('%-10s',hk.data_type); % ensure it is 10 chars from left 0095 % fwrite(fid, data_type(1:10), 'uchar'); 0096 pad = zeros(1, 10-length(hk.data_type)); 0097 hk.data_type = [hk.data_type char(pad)]; 0098 fwrite(fid, hk.data_type(1:10), 'uchar'); 0099 0100 % db_name = sprintf('%-18s', hk.db_name); % ensure it is 18 chars from left 0101 % fwrite(fid, db_name(1:18), 'uchar'); 0102 pad = zeros(1, 18-length(hk.db_name)); 0103 hk.db_name = [hk.db_name char(pad)]; 0104 fwrite(fid, hk.db_name(1:18), 'uchar'); 0105 0106 fwrite(fid, hk.extents(1), 'int32'); 0107 fwrite(fid, hk.session_error(1), 'int16'); 0108 fwrite(fid, hk.regular(1), 'uchar'); % might be uint8 0109 0110 % fwrite(fid, hk.hkey_un0(1), 'uchar'); 0111 % fwrite(fid, hk.hkey_un0(1), 'uint8'); 0112 fwrite(fid, hk.dim_info(1), 'uchar'); 0113 0114 return; % header_key 0115 0116 0117 %--------------------------------------------------------------------- 0118 function image_dimension(fid, dime) 0119 0120 % Original header structures 0121 % struct image_dimension 0122 % { /* off + size */ 0123 % short int dim[8]; /* 0 + 16 */ 0124 % float intent_p1; % char vox_units[4]; /* 16 + 4 */ 0125 % float intent_p2; % char cal_units[8]; /* 20 + 4 */ 0126 % float intent_p3; % char cal_units[8]; /* 24 + 4 */ 0127 % short int intent_code; % short int unused1; /* 28 + 2 */ 0128 % short int datatype; /* 30 + 2 */ 0129 % short int bitpix; /* 32 + 2 */ 0130 % short int slice_start; % short int dim_un0; /* 34 + 2 */ 0131 % float pixdim[8]; /* 36 + 32 */ 0132 % /* 0133 % pixdim[] specifies the voxel dimensions: 0134 % pixdim[1] - voxel width 0135 % pixdim[2] - voxel height 0136 % pixdim[3] - interslice distance 0137 % pixdim[4] - volume timing, in msec 0138 % ..etc 0139 % */ 0140 % float vox_offset; /* 68 + 4 */ 0141 % float scl_slope; % float roi_scale; /* 72 + 4 */ 0142 % float scl_inter; % float funused1; /* 76 + 4 */ 0143 % short slice_end; % float funused2; /* 80 + 2 */ 0144 % char slice_code; % float funused2; /* 82 + 1 */ 0145 % char xyzt_units; % float funused2; /* 83 + 1 */ 0146 % float cal_max; /* 84 + 4 */ 0147 % float cal_min; /* 88 + 4 */ 0148 % float slice_duration; % int compressed; /* 92 + 4 */ 0149 % float toffset; % int verified; /* 96 + 4 */ 0150 % int glmax; /* 100 + 4 */ 0151 % int glmin; /* 104 + 4 */ 0152 % }; /* total=108 bytes */ 0153 0154 fwrite(fid, dime.dim(1:8), 'int16'); 0155 fwrite(fid, dime.intent_p1(1), 'float32'); 0156 fwrite(fid, dime.intent_p2(1), 'float32'); 0157 fwrite(fid, dime.intent_p3(1), 'float32'); 0158 fwrite(fid, dime.intent_code(1), 'int16'); 0159 fwrite(fid, dime.datatype(1), 'int16'); 0160 fwrite(fid, dime.bitpix(1), 'int16'); 0161 fwrite(fid, dime.slice_start(1), 'int16'); 0162 fwrite(fid, dime.pixdim(1:8), 'float32'); 0163 fwrite(fid, dime.vox_offset(1), 'float32'); 0164 fwrite(fid, dime.scl_slope(1), 'float32'); 0165 fwrite(fid, dime.scl_inter(1), 'float32'); 0166 fwrite(fid, dime.slice_end(1), 'int16'); 0167 fwrite(fid, dime.slice_code(1), 'uchar'); 0168 fwrite(fid, dime.xyzt_units(1), 'uchar'); 0169 fwrite(fid, dime.cal_max(1), 'float32'); 0170 fwrite(fid, dime.cal_min(1), 'float32'); 0171 fwrite(fid, dime.slice_duration(1), 'float32'); 0172 fwrite(fid, dime.toffset(1), 'float32'); 0173 fwrite(fid, dime.glmax(1), 'int32'); 0174 fwrite(fid, dime.glmin(1), 'int32'); 0175 0176 return; % image_dimension 0177 0178 0179 %--------------------------------------------------------------------- 0180 function data_history(fid, hist) 0181 0182 % Original header structures 0183 %struct data_history 0184 % { /* off + size */ 0185 % char descrip[80]; /* 0 + 80 */ 0186 % char aux_file[24]; /* 80 + 24 */ 0187 % short int qform_code; /* 104 + 2 */ 0188 % short int sform_code; /* 106 + 2 */ 0189 % float quatern_b; /* 108 + 4 */ 0190 % float quatern_c; /* 112 + 4 */ 0191 % float quatern_d; /* 116 + 4 */ 0192 % float qoffset_x; /* 120 + 4 */ 0193 % float qoffset_y; /* 124 + 4 */ 0194 % float qoffset_z; /* 128 + 4 */ 0195 % float srow_x[4]; /* 132 + 16 */ 0196 % float srow_y[4]; /* 148 + 16 */ 0197 % float srow_z[4]; /* 164 + 16 */ 0198 % char intent_name[16]; /* 180 + 16 */ 0199 % char magic[4]; % int smin; /* 196 + 4 */ 0200 % }; /* total=200 bytes */ 0201 0202 % descrip = sprintf('%-80s', hist.descrip); % 80 chars from left 0203 % fwrite(fid, descrip(1:80), 'uchar'); 0204 pad = zeros(1, 80-length(hist.descrip)); 0205 hist.descrip = [hist.descrip char(pad)]; 0206 fwrite(fid, hist.descrip(1:80), 'uchar'); 0207 0208 % aux_file = sprintf('%-24s', hist.aux_file); % 24 chars from left 0209 % fwrite(fid, aux_file(1:24), 'uchar'); 0210 pad = zeros(1, 24-length(hist.aux_file)); 0211 hist.aux_file = [hist.aux_file char(pad)]; 0212 fwrite(fid, hist.aux_file(1:24), 'uchar'); 0213 0214 fwrite(fid, hist.qform_code, 'int16'); 0215 fwrite(fid, hist.sform_code, 'int16'); 0216 fwrite(fid, hist.quatern_b, 'float32'); 0217 fwrite(fid, hist.quatern_c, 'float32'); 0218 fwrite(fid, hist.quatern_d, 'float32'); 0219 fwrite(fid, hist.qoffset_x, 'float32'); 0220 fwrite(fid, hist.qoffset_y, 'float32'); 0221 fwrite(fid, hist.qoffset_z, 'float32'); 0222 fwrite(fid, hist.srow_x(1:4), 'float32'); 0223 fwrite(fid, hist.srow_y(1:4), 'float32'); 0224 fwrite(fid, hist.srow_z(1:4), 'float32'); 0225 0226 % intent_name = sprintf('%-16s', hist.intent_name); % 16 chars from left 0227 % fwrite(fid, intent_name(1:16), 'uchar'); 0228 pad = zeros(1, 16-length(hist.intent_name)); 0229 hist.intent_name = [hist.intent_name char(pad)]; 0230 fwrite(fid, hist.intent_name(1:16), 'uchar'); 0231 0232 % magic = sprintf('%-4s', hist.magic); % 4 chars from left 0233 % fwrite(fid, magic(1:4), 'uchar'); 0234 pad = zeros(1, 4-length(hist.magic)); 0235 hist.magic = [hist.magic char(pad)]; 0236 fwrite(fid, hist.magic(1:4), 'uchar'); 0237 0238 return; % data_history 0239