save_untouch_nii.m 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. % Save NIFTI or ANALYZE dataset that is loaded by "load_untouch_nii.m".
  2. % The output image format and file extension will be the same as the
  3. % input one (NIFTI.nii, NIFTI.img or ANALYZE.img). Therefore, any file
  4. % extension that you specified will be ignored.
  5. %
  6. % Usage: save_untouch_nii(nii, filename)
  7. %
  8. % nii - nii structure that is loaded by "load_untouch_nii.m"
  9. %
  10. % filename - NIFTI or ANALYZE file name.
  11. %
  12. % - Jimmy Shen (jimmy@rotman-baycrest.on.ca)
  13. %
  14. function save_untouch_nii(nii, filename)
  15. if ~exist('nii','var') | isempty(nii) | ~isfield(nii,'hdr') | ...
  16. ~isfield(nii,'img') | ~exist('filename','var') | isempty(filename)
  17. error('Usage: save_untouch_nii(nii, filename)');
  18. end
  19. if ~isfield(nii,'untouch') | nii.untouch == 0
  20. error('Usage: please use ''save_nii.m'' for the modified structure.');
  21. end
  22. if isfield(nii.hdr.hist,'magic') & strcmp(nii.hdr.hist.magic(1:3),'ni1')
  23. filetype = 1;
  24. elseif isfield(nii.hdr.hist,'magic') & strcmp(nii.hdr.hist.magic(1:3),'n+1')
  25. filetype = 2;
  26. else
  27. filetype = 0;
  28. end
  29. v = version;
  30. % Check file extension. If .gz, unpack it into temp folder
  31. %
  32. if length(filename) > 2 & strcmp(filename(end-2:end), '.gz')
  33. if ~strcmp(filename(end-6:end), '.img.gz') & ...
  34. ~strcmp(filename(end-6:end), '.hdr.gz') & ...
  35. ~strcmp(filename(end-6:end), '.nii.gz')
  36. error('Please check filename.');
  37. end
  38. if str2num(v(1:3)) < 7.1 | ~usejava('jvm')
  39. error('Please use MATLAB 7.1 (with java) and above, or run gunzip outside MATLAB.');
  40. else
  41. gzFile = 1;
  42. filename = filename(1:end-3);
  43. end
  44. end
  45. [p,f] = fileparts(filename);
  46. fileprefix = fullfile(p, f);
  47. write_nii(nii, filetype, fileprefix);
  48. % gzip output file if requested
  49. %
  50. if exist('gzFile', 'var')
  51. if filetype == 1
  52. gzip([fileprefix, '.img']);
  53. delete([fileprefix, '.img']);
  54. gzip([fileprefix, '.hdr']);
  55. delete([fileprefix, '.hdr']);
  56. elseif filetype == 2
  57. gzip([fileprefix, '.nii']);
  58. delete([fileprefix, '.nii']);
  59. end;
  60. end;
  61. % % So earlier versions of SPM can also open it with correct originator
  62. % %
  63. % if filetype == 0
  64. % M=[[diag(nii.hdr.dime.pixdim(2:4)) -[nii.hdr.hist.originator(1:3).*nii.hdr.dime.pixdim(2:4)]'];[0 0 0 1]];
  65. % save(fileprefix, 'M');
  66. % elseif filetype == 1
  67. % M=[];
  68. % save(fileprefix, 'M');
  69. %end
  70. return % save_untouch_nii
  71. %-----------------------------------------------------------------------------------
  72. function write_nii(nii, filetype, fileprefix)
  73. hdr = nii.hdr;
  74. if isfield(nii,'ext') & ~isempty(nii.ext)
  75. ext = nii.ext;
  76. [ext, esize_total] = verify_nii_ext(ext);
  77. else
  78. ext = [];
  79. end
  80. switch double(hdr.dime.datatype),
  81. case 1,
  82. hdr.dime.bitpix = int16(1 ); precision = 'ubit1';
  83. case 2,
  84. hdr.dime.bitpix = int16(8 ); precision = 'uint8';
  85. case 4,
  86. hdr.dime.bitpix = int16(16); precision = 'int16';
  87. case 8,
  88. hdr.dime.bitpix = int16(32); precision = 'int32';
  89. case 16,
  90. hdr.dime.bitpix = int16(32); precision = 'float32';
  91. case 32,
  92. hdr.dime.bitpix = int16(64); precision = 'float32';
  93. case 64,
  94. hdr.dime.bitpix = int16(64); precision = 'float64';
  95. case 128,
  96. hdr.dime.bitpix = int16(24); precision = 'uint8';
  97. case 256
  98. hdr.dime.bitpix = int16(8 ); precision = 'int8';
  99. case 512
  100. hdr.dime.bitpix = int16(16); precision = 'uint16';
  101. case 768
  102. hdr.dime.bitpix = int16(32); precision = 'uint32';
  103. case 1024
  104. hdr.dime.bitpix = int16(64); precision = 'int64';
  105. case 1280
  106. hdr.dime.bitpix = int16(64); precision = 'uint64';
  107. case 1792,
  108. hdr.dime.bitpix = int16(128); precision = 'float64';
  109. otherwise
  110. error('This datatype is not supported');
  111. end
  112. % hdr.dime.glmax = round(double(max(nii.img(:))));
  113. % hdr.dime.glmin = round(double(min(nii.img(:))));
  114. if filetype == 2
  115. fid = fopen(sprintf('%s.nii',fileprefix),'w');
  116. if fid < 0,
  117. msg = sprintf('Cannot open file %s.nii.',fileprefix);
  118. error(msg);
  119. end
  120. hdr.dime.vox_offset = 352;
  121. if ~isempty(ext)
  122. hdr.dime.vox_offset = hdr.dime.vox_offset + esize_total;
  123. end
  124. hdr.hist.magic = 'n+1';
  125. save_untouch_nii_hdr(hdr, fid);
  126. if ~isempty(ext)
  127. save_nii_ext(ext, fid);
  128. end
  129. elseif filetype == 1
  130. fid = fopen(sprintf('%s.hdr',fileprefix),'w');
  131. if fid < 0,
  132. msg = sprintf('Cannot open file %s.hdr.',fileprefix);
  133. error(msg);
  134. end
  135. hdr.dime.vox_offset = 0;
  136. hdr.hist.magic = 'ni1';
  137. save_untouch_nii_hdr(hdr, fid);
  138. if ~isempty(ext)
  139. save_nii_ext(ext, fid);
  140. end
  141. fclose(fid);
  142. fid = fopen(sprintf('%s.img',fileprefix),'w');
  143. else
  144. fid = fopen(sprintf('%s.hdr',fileprefix),'w');
  145. if fid < 0,
  146. msg = sprintf('Cannot open file %s.hdr.',fileprefix);
  147. error(msg);
  148. end
  149. save_untouch0_nii_hdr(hdr, fid);
  150. fclose(fid);
  151. fid = fopen(sprintf('%s.img',fileprefix),'w');
  152. end
  153. ScanDim = double(hdr.dime.dim(5)); % t
  154. SliceDim = double(hdr.dime.dim(4)); % z
  155. RowDim = double(hdr.dime.dim(3)); % y
  156. PixelDim = double(hdr.dime.dim(2)); % x
  157. SliceSz = double(hdr.dime.pixdim(4));
  158. RowSz = double(hdr.dime.pixdim(3));
  159. PixelSz = double(hdr.dime.pixdim(2));
  160. x = 1:PixelDim;
  161. if filetype == 2 & isempty(ext)
  162. skip_bytes = double(hdr.dime.vox_offset) - 348;
  163. else
  164. skip_bytes = 0;
  165. end
  166. if double(hdr.dime.datatype) == 128
  167. % RGB planes are expected to be in the 4th dimension of nii.img
  168. %
  169. if(size(nii.img,4)~=3)
  170. error(['The NII structure does not appear to have 3 RGB color planes in the 4th dimension']);
  171. end
  172. nii.img = permute(nii.img, [4 1 2 3 5 6 7 8]);
  173. end
  174. % For complex float32 or complex float64, voxel values
  175. % include [real, imag]
  176. %
  177. if hdr.dime.datatype == 32 | hdr.dime.datatype == 1792
  178. real_img = real(nii.img(:))';
  179. nii.img = imag(nii.img(:))';
  180. nii.img = [real_img; nii.img];
  181. end
  182. if skip_bytes
  183. fwrite(fid, zeros(1,skip_bytes), 'uint8');
  184. end
  185. fwrite(fid, nii.img, precision);
  186. % fwrite(fid, nii.img, precision, skip_bytes); % error using skip
  187. fclose(fid);
  188. return; % write_nii