load_nii_hdr.m 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. % internal function
  2. % - Jimmy Shen (jimmy@rotman-baycrest.on.ca)
  3. function [hdr, filetype, fileprefix, machine] = load_nii_hdr(fileprefix)
  4. if ~exist('fileprefix','var'),
  5. error('Usage: [hdr, filetype, fileprefix, machine] = load_nii_hdr(filename)');
  6. end
  7. machine = 'ieee-le';
  8. new_ext = 0;
  9. if findstr('.nii',fileprefix) & strcmp(fileprefix(end-3:end), '.nii')
  10. new_ext = 1;
  11. fileprefix(end-3:end)='';
  12. end
  13. if findstr('.hdr',fileprefix) & strcmp(fileprefix(end-3:end), '.hdr')
  14. fileprefix(end-3:end)='';
  15. end
  16. if findstr('.img',fileprefix) & strcmp(fileprefix(end-3:end), '.img')
  17. fileprefix(end-3:end)='';
  18. end
  19. if new_ext
  20. fn = sprintf('%s.nii',fileprefix);
  21. if ~exist(fn)
  22. msg = sprintf('Cannot find file "%s.nii".', fileprefix);
  23. error(msg);
  24. end
  25. else
  26. fn = sprintf('%s.hdr',fileprefix);
  27. if ~exist(fn)
  28. msg = sprintf('Cannot find file "%s.hdr".', fileprefix);
  29. error(msg);
  30. end
  31. end
  32. fid = fopen(fn,'r',machine);
  33. if fid < 0,
  34. msg = sprintf('Cannot open file %s.',fn);
  35. error(msg);
  36. else
  37. fseek(fid,0,'bof');
  38. if fread(fid,1,'int32') == 348
  39. hdr = read_header(fid);
  40. fclose(fid);
  41. else
  42. fclose(fid);
  43. % first try reading the opposite endian to 'machine'
  44. %
  45. switch machine,
  46. case 'ieee-le', machine = 'ieee-be';
  47. case 'ieee-be', machine = 'ieee-le';
  48. end
  49. fid = fopen(fn,'r',machine);
  50. if fid < 0,
  51. msg = sprintf('Cannot open file %s.',fn);
  52. error(msg);
  53. else
  54. fseek(fid,0,'bof');
  55. if fread(fid,1,'int32') ~= 348
  56. % Now throw an error
  57. %
  58. msg = sprintf('File "%s" is corrupted.',fn);
  59. error(msg);
  60. end
  61. hdr = read_header(fid);
  62. fclose(fid);
  63. end
  64. end
  65. end
  66. if strcmp(hdr.hist.magic, 'n+1')
  67. filetype = 2;
  68. elseif strcmp(hdr.hist.magic, 'ni1')
  69. filetype = 1;
  70. else
  71. filetype = 0;
  72. end
  73. return % load_nii_hdr
  74. %---------------------------------------------------------------------
  75. function [ dsr ] = read_header(fid)
  76. % Original header structures
  77. % struct dsr
  78. % {
  79. % struct header_key hk; /* 0 + 40 */
  80. % struct image_dimension dime; /* 40 + 108 */
  81. % struct data_history hist; /* 148 + 200 */
  82. % }; /* total= 348 bytes*/
  83. dsr.hk = header_key(fid);
  84. dsr.dime = image_dimension(fid);
  85. dsr.hist = data_history(fid);
  86. % For Analyze data format
  87. %
  88. if ~strcmp(dsr.hist.magic, 'n+1') & ~strcmp(dsr.hist.magic, 'ni1')
  89. dsr.hist.qform_code = 0;
  90. dsr.hist.sform_code = 0;
  91. end
  92. return % read_header
  93. %---------------------------------------------------------------------
  94. function [ hk ] = header_key(fid)
  95. fseek(fid,0,'bof');
  96. % Original header structures
  97. % struct header_key /* header key */
  98. % { /* off + size */
  99. % int sizeof_hdr /* 0 + 4 */
  100. % char data_type[10]; /* 4 + 10 */
  101. % char db_name[18]; /* 14 + 18 */
  102. % int extents; /* 32 + 4 */
  103. % short int session_error; /* 36 + 2 */
  104. % char regular; /* 38 + 1 */
  105. % char dim_info; % char hkey_un0; /* 39 + 1 */
  106. % }; /* total=40 bytes */
  107. %
  108. % int sizeof_header Should be 348.
  109. % char regular Must be 'r' to indicate that all images and
  110. % volumes are the same size.
  111. v6 = version;
  112. if str2num(v6(1))<6
  113. directchar = '*char';
  114. else
  115. directchar = 'uchar=>char';
  116. end
  117. hk.sizeof_hdr = fread(fid, 1,'int32')'; % should be 348!
  118. hk.data_type = deblank(fread(fid,10,directchar)');
  119. hk.db_name = deblank(fread(fid,18,directchar)');
  120. hk.extents = fread(fid, 1,'int32')';
  121. hk.session_error = fread(fid, 1,'int16')';
  122. hk.regular = fread(fid, 1,directchar)';
  123. hk.dim_info = fread(fid, 1,'uchar')';
  124. return % header_key
  125. %---------------------------------------------------------------------
  126. function [ dime ] = image_dimension(fid)
  127. % Original header structures
  128. % struct image_dimension
  129. % { /* off + size */
  130. % short int dim[8]; /* 0 + 16 */
  131. % /*
  132. % dim[0] Number of dimensions in database; usually 4.
  133. % dim[1] Image X dimension; number of *pixels* in an image row.
  134. % dim[2] Image Y dimension; number of *pixel rows* in slice.
  135. % dim[3] Volume Z dimension; number of *slices* in a volume.
  136. % dim[4] Time points; number of volumes in database
  137. % */
  138. % float intent_p1; % char vox_units[4]; /* 16 + 4 */
  139. % float intent_p2; % char cal_units[8]; /* 20 + 4 */
  140. % float intent_p3; % char cal_units[8]; /* 24 + 4 */
  141. % short int intent_code; % short int unused1; /* 28 + 2 */
  142. % short int datatype; /* 30 + 2 */
  143. % short int bitpix; /* 32 + 2 */
  144. % short int slice_start; % short int dim_un0; /* 34 + 2 */
  145. % float pixdim[8]; /* 36 + 32 */
  146. % /*
  147. % pixdim[] specifies the voxel dimensions:
  148. % pixdim[1] - voxel width, mm
  149. % pixdim[2] - voxel height, mm
  150. % pixdim[3] - slice thickness, mm
  151. % pixdim[4] - volume timing, in msec
  152. % ..etc
  153. % */
  154. % float vox_offset; /* 68 + 4 */
  155. % float scl_slope; % float roi_scale; /* 72 + 4 */
  156. % float scl_inter; % float funused1; /* 76 + 4 */
  157. % short slice_end; % float funused2; /* 80 + 2 */
  158. % char slice_code; % float funused2; /* 82 + 1 */
  159. % char xyzt_units; % float funused2; /* 83 + 1 */
  160. % float cal_max; /* 84 + 4 */
  161. % float cal_min; /* 88 + 4 */
  162. % float slice_duration; % int compressed; /* 92 + 4 */
  163. % float toffset; % int verified; /* 96 + 4 */
  164. % int glmax; /* 100 + 4 */
  165. % int glmin; /* 104 + 4 */
  166. % }; /* total=108 bytes */
  167. dime.dim = fread(fid,8,'int16')';
  168. dime.intent_p1 = fread(fid,1,'float32')';
  169. dime.intent_p2 = fread(fid,1,'float32')';
  170. dime.intent_p3 = fread(fid,1,'float32')';
  171. dime.intent_code = fread(fid,1,'int16')';
  172. dime.datatype = fread(fid,1,'int16')';
  173. dime.bitpix = fread(fid,1,'int16')';
  174. dime.slice_start = fread(fid,1,'int16')';
  175. dime.pixdim = fread(fid,8,'float32')';
  176. dime.vox_offset = fread(fid,1,'float32')';
  177. dime.scl_slope = fread(fid,1,'float32')';
  178. dime.scl_inter = fread(fid,1,'float32')';
  179. dime.slice_end = fread(fid,1,'int16')';
  180. dime.slice_code = fread(fid,1,'uchar')';
  181. dime.xyzt_units = fread(fid,1,'uchar')';
  182. dime.cal_max = fread(fid,1,'float32')';
  183. dime.cal_min = fread(fid,1,'float32')';
  184. dime.slice_duration = fread(fid,1,'float32')';
  185. dime.toffset = fread(fid,1,'float32')';
  186. dime.glmax = fread(fid,1,'int32')';
  187. dime.glmin = fread(fid,1,'int32')';
  188. return % image_dimension
  189. %---------------------------------------------------------------------
  190. function [ hist ] = data_history(fid)
  191. % Original header structures
  192. % struct data_history
  193. % { /* off + size */
  194. % char descrip[80]; /* 0 + 80 */
  195. % char aux_file[24]; /* 80 + 24 */
  196. % short int qform_code; /* 104 + 2 */
  197. % short int sform_code; /* 106 + 2 */
  198. % float quatern_b; /* 108 + 4 */
  199. % float quatern_c; /* 112 + 4 */
  200. % float quatern_d; /* 116 + 4 */
  201. % float qoffset_x; /* 120 + 4 */
  202. % float qoffset_y; /* 124 + 4 */
  203. % float qoffset_z; /* 128 + 4 */
  204. % float srow_x[4]; /* 132 + 16 */
  205. % float srow_y[4]; /* 148 + 16 */
  206. % float srow_z[4]; /* 164 + 16 */
  207. % char intent_name[16]; /* 180 + 16 */
  208. % char magic[4]; % int smin; /* 196 + 4 */
  209. % }; /* total=200 bytes */
  210. v6 = version;
  211. if str2num(v6(1))<6
  212. directchar = '*char';
  213. else
  214. directchar = 'uchar=>char';
  215. end
  216. hist.descrip = deblank(fread(fid,80,directchar)');
  217. hist.aux_file = deblank(fread(fid,24,directchar)');
  218. hist.qform_code = fread(fid,1,'int16')';
  219. hist.sform_code = fread(fid,1,'int16')';
  220. hist.quatern_b = fread(fid,1,'float32')';
  221. hist.quatern_c = fread(fid,1,'float32')';
  222. hist.quatern_d = fread(fid,1,'float32')';
  223. hist.qoffset_x = fread(fid,1,'float32')';
  224. hist.qoffset_y = fread(fid,1,'float32')';
  225. hist.qoffset_z = fread(fid,1,'float32')';
  226. hist.srow_x = fread(fid,4,'float32')';
  227. hist.srow_y = fread(fid,4,'float32')';
  228. hist.srow_z = fread(fid,4,'float32')';
  229. hist.intent_name = deblank(fread(fid,16,directchar)');
  230. hist.magic = deblank(fread(fid,4,directchar)');
  231. fseek(fid,253,'bof');
  232. hist.originator = fread(fid, 5,'int16')';
  233. return % data_history