avw_hdr_read - read Analyze format data header (*.hdr) [ avw, machine ] = avw_hdr_read(fileprefix, [machine]) fileprefix - string filename (without .hdr); the file name can be given as a full path or relative to the current directory. machine - a string, see machineformat in fread for details. The default here is 'ieee-le' but the routine will automatically switch between little and big endian to read any such Analyze header. It reports the appropriate machine format and can return the machine value. avw.hdr - a struct, all fields returned from the header. For details, find a good description on the web or see the Analyze File Format pdf in the mri_toolbox doc folder or read this .m file. This function is called by avw_img_read See also avw_hdr_write, avw_hdr_make, avw_view_hdr, avw_view
0001 function [ avw, machine ] = avw_hdr_read(fileprefix, machine) 0002 0003 % avw_hdr_read - read Analyze format data header (*.hdr) 0004 % 0005 % [ avw, machine ] = avw_hdr_read(fileprefix, [machine]) 0006 % 0007 % fileprefix - string filename (without .hdr); the file name 0008 % can be given as a full path or relative to the 0009 % current directory. 0010 % 0011 % machine - a string, see machineformat in fread for details. 0012 % The default here is 'ieee-le' but the routine 0013 % will automatically switch between little and big 0014 % endian to read any such Analyze header. It 0015 % reports the appropriate machine format and can 0016 % return the machine value. 0017 % 0018 % avw.hdr - a struct, all fields returned from the header. 0019 % For details, find a good description on the web 0020 % or see the Analyze File Format pdf in the 0021 % mri_toolbox doc folder or read this .m file. 0022 % 0023 % This function is called by avw_img_read 0024 % 0025 % See also avw_hdr_write, avw_hdr_make, avw_view_hdr, avw_view 0026 % 0027 0028 % $Revision: 1332 $ $Date:: 2011-02-24 15:57:20 +0900#$ 0029 0030 % Licence: GNU GPL, no express or implied warranties 0031 % History: 05/2002, Darren.Weber@flinders.edu.au 0032 % The Analyze format and c code below is copyright 0033 % (c) Copyright, 1986-1995 0034 % Biomedical Imaging Resource, Mayo Foundation 0035 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0036 0037 version = '[$Revision: 1332 $]'; 0038 fprintf('\nAVW_HDR_READ [v%s]\n',version(12:16)); tic; 0039 0040 if ~exist('fileprefix','var'), 0041 msg = sprintf('...no input fileprefix - see help avw_hdr_read\n\n'); 0042 error(msg); 0043 end 0044 if ~exist('machine','var'), machine = 'ieee-le'; end 0045 0046 0047 if findstr('.hdr',fileprefix), 0048 % fprintf('...removing .hdr extension from ''%s''\n',fileprefix); 0049 fileprefix = strrep(fileprefix,'.hdr',''); 0050 end 0051 if findstr('.img',fileprefix), 0052 % fprintf('...removing .img extension from ''%s''\n',fileprefix); 0053 fileprefix = strrep(fileprefix,'.img',''); 0054 end 0055 file = sprintf('%s.hdr',fileprefix); 0056 0057 if exist(file), 0058 fprintf('...reading %s Analyze format',machine); 0059 % rhayashi added encoding 0060 fid = fopen_ascii_encoding(file, 'r', machine); 0061 0062 avw.hdr = read_header(fid); 0063 avw.fileprefix = fileprefix; 0064 fclose(fid); 0065 0066 if ~isequal(avw.hdr.hk.sizeof_hdr,348), 0067 fprintf('...failed.\n'); 0068 % first try reading the opposite endian to 'machine' 0069 switch machine, 0070 case 'ieee-le', machine = 'ieee-be'; 0071 case 'ieee-be', machine = 'ieee-le'; 0072 end 0073 fprintf('...reading %s Analyze format',machine); 0074 % rhayashi added encoding 0075 fid = fopen_ascii_encoding(file, 'r', machine); 0076 avw.hdr = read_header(fid); 0077 avw.fileprefix = fileprefix; 0078 fclose(fid); 0079 end 0080 if ~isequal(avw.hdr.hk.sizeof_hdr,348), 0081 % Now throw an error 0082 fprintf('...failed.\n'); 0083 msg = sprintf('...size of header not equal to 348 bytes!\n\n'); 0084 error(msg); 0085 end 0086 else 0087 msg = sprintf('...cannot find file %s.hdr\n\n',file); 0088 error(msg); 0089 end 0090 0091 t=toc; fprintf('...done (%5.2f sec).\n',t); 0092 0093 return 0094 0095 function [ fid ] = fopen_ascii_encoding(file, mode, machine) 0096 0097 if vb_matlab_version('>=', '7.2') 0098 fid = fopen(file, mode, machine, 'US-ASCII'); 0099 else 0100 fid = fopen(file, mode, machine); 0101 end 0102 0103 0104 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0105 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0106 function [ dsr ] = read_header(fid) 0107 0108 % Original header structures - ANALYZE 7.5 0109 %struct dsr 0110 % { 0111 % struct header_key hk; /* 0 + 40 */ 0112 % struct image_dimension dime; /* 40 + 108 */ 0113 % struct data_history hist; /* 148 + 200 */ 0114 % }; /* total= 348 bytes*/ 0115 dsr.hk = header_key(fid); 0116 dsr.dime = image_dimension(fid); 0117 dsr.hist = data_history(fid); 0118 0119 return 0120 0121 0122 0123 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0124 function [hk] = header_key(fid) 0125 0126 % The required elements in the header_key substructure are: 0127 % 0128 % int sizeof_header Must indicate the byte size of the header file. 0129 % int extents Should be 16384, the image file is created as 0130 % contiguous with a minimum extent size. 0131 % char regular Must be 'r' to indicate that all images and 0132 % volumes are the same size. 0133 0134 % Original header structures - ANALYZE 7.5 0135 % struct header_key /* header key */ 0136 % { /* off + size */ 0137 % int sizeof_hdr /* 0 + 4 */ 0138 % char data_type[10]; /* 4 + 10 */ 0139 % char db_name[18]; /* 14 + 18 */ 0140 % int extents; /* 32 + 4 */ 0141 % short int session_error; /* 36 + 2 */ 0142 % char regular; /* 38 + 1 */ 0143 % char hkey_un0; /* 39 + 1 */ 0144 % }; /* total=40 bytes */ 0145 0146 fseek(fid,0,'bof'); 0147 0148 hk.sizeof_hdr = fread(fid, 1,'*int32'); % should be 348! 0149 hk.data_type = fread(fid,10,'*char')'; 0150 hk.db_name = fread(fid,18,'*char')'; 0151 hk.extents = fread(fid, 1,'*int32'); 0152 hk.session_error = fread(fid, 1,'*int16'); 0153 hk.regular = fread(fid, 1,'*char')'; % might be uint8 0154 hk.hkey_un0 = fread(fid, 1,'*uint8')'; 0155 0156 % check if this value was a char zero 0157 if hk.hkey_un0 == 48, 0158 hk.hkey_un0 = 0; 0159 end 0160 0161 return 0162 0163 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0164 function [ dime ] = image_dimension(fid) 0165 0166 %struct image_dimension 0167 % { /* off + size */ 0168 % short int dim[8]; /* 0 + 16 */ 0169 % /* 0170 % dim[0] Number of dimensions in database; usually 4. 0171 % dim[1] Image X dimension; number of *pixels* in an image row. 0172 % dim[2] Image Y dimension; number of *pixel rows* in slice. 0173 % dim[3] Volume Z dimension; number of *slices* in a volume. 0174 % dim[4] Time points; number of volumes in database 0175 % */ 0176 % char vox_units[4]; /* 16 + 4 */ 0177 % char cal_units[8]; /* 20 + 8 */ 0178 % short int unused1; /* 28 + 2 */ 0179 % short int datatype; /* 30 + 2 */ 0180 % short int bitpix; /* 32 + 2 */ 0181 % short int dim_un0; /* 34 + 2 */ 0182 % float pixdim[8]; /* 36 + 32 */ 0183 % /* 0184 % pixdim[] specifies the voxel dimensions: 0185 % pixdim[1] - voxel width, mm 0186 % pixdim[2] - voxel height, mm 0187 % pixdim[3] - slice thickness, mm 0188 % pixdim[4] - volume timing, in msec 0189 % ..etc 0190 % */ 0191 % float vox_offset; /* 68 + 4 */ 0192 % float roi_scale; /* 72 + 4 */ 0193 % float funused1; /* 76 + 4 */ 0194 % float funused2; /* 80 + 4 */ 0195 % float cal_max; /* 84 + 4 */ 0196 % float cal_min; /* 88 + 4 */ 0197 % int compressed; /* 92 + 4 */ 0198 % int verified; /* 96 + 4 */ 0199 % int glmax; /* 100 + 4 */ 0200 % int glmin; /* 104 + 4 */ 0201 % }; /* total=108 bytes */ 0202 0203 dime.dim = fread(fid,8,'int16')'; 0204 dime.vox_units = fread(fid,4,'*char')'; 0205 dime.cal_units = fread(fid,8,'*char')'; 0206 dime.unused1 = fread(fid,1,'*int16'); 0207 dime.datatype = fread(fid,1,'*int16'); 0208 dime.bitpix = fread(fid,1,'*int16'); 0209 dime.dim_un0 = fread(fid,1,'*int16'); 0210 dime.pixdim = fread(fid,8,'float')'; 0211 dime.vox_offset = fread(fid,1,'*float'); 0212 dime.roi_scale = fread(fid,1,'*float'); 0213 dime.funused1 = fread(fid,1,'*float'); 0214 dime.funused2 = fread(fid,1,'*float'); 0215 dime.cal_max = fread(fid,1,'*float'); 0216 dime.cal_min = fread(fid,1,'*float'); 0217 dime.compressed = fread(fid,1,'*int32'); 0218 dime.verified = fread(fid,1,'*int32'); 0219 dime.glmax = fread(fid,1,'*int32'); 0220 dime.glmin = fread(fid,1,'*int32'); 0221 0222 if dime.dim(1) < 4, % Number of dimensions in database; usually 4. 0223 fprintf('...ensuring 4 dimensions in avw.hdr.dime.dim\n'); 0224 dime.dim(1) = int16(4); 0225 end 0226 if dime.dim(5) < 1, % Time points; number of volumes in database 0227 fprintf('...ensuring at least 1 volume in avw.hdr.dime.dim(5)\n'); 0228 dime.dim(5) = int16(1); 0229 end 0230 0231 return 0232 0233 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0234 function [ hist ] = data_history(fid) 0235 0236 % Original header structures - ANALYZE 7.5 0237 %struct data_history 0238 % { /* off + size */ 0239 % char descrip[80]; /* 0 + 80 */ 0240 % char aux_file[24]; /* 80 + 24 */ 0241 % char orient; /* 104 + 1 */ 0242 % char originator[10]; /* 105 + 10 */ 0243 % char generated[10]; /* 115 + 10 */ 0244 % char scannum[10]; /* 125 + 10 */ 0245 % char patient_id[10]; /* 135 + 10 */ 0246 % char exp_date[10]; /* 145 + 10 */ 0247 % char exp_time[10]; /* 155 + 10 */ 0248 % char hist_un0[3]; /* 165 + 3 */ 0249 % int views /* 168 + 4 */ 0250 % int vols_added; /* 172 + 4 */ 0251 % int start_field; /* 176 + 4 */ 0252 % int field_skip; /* 180 + 4 */ 0253 % int omax; /* 184 + 4 */ 0254 % int omin; /* 188 + 4 */ 0255 % int smax; /* 192 + 4 */ 0256 % int smin; /* 196 + 4 */ 0257 % }; /* total=200 bytes */ 0258 0259 hist.descrip = fread(fid,80,'*char')'; 0260 hist.aux_file = fread(fid,24,'*char')'; 0261 hist.orient = fread(fid, 1,'*uint8'); % see note below on char 0262 % Modified by M. Sato 0263 hist.originator = fread(fid,5,'int16')'; % SPM origin field 0264 0265 hist.generated = fread(fid,10,'*char')'; 0266 hist.scannum = fread(fid,10,'*char')'; 0267 hist.patient_id = fread(fid,10,'*char')'; 0268 hist.exp_date = fread(fid,10,'*char')'; 0269 hist.exp_time = fread(fid,10,'*char')'; 0270 hist.hist_un0 = fread(fid, 3,'*char')'; 0271 hist.views = fread(fid, 1,'*int32'); 0272 hist.vols_added = fread(fid, 1,'*int32'); 0273 hist.start_field = fread(fid, 1,'*int32'); 0274 hist.field_skip = fread(fid, 1,'*int32'); 0275 hist.omax = fread(fid, 1,'*int32'); 0276 hist.omin = fread(fid, 1,'*int32'); 0277 hist.smax = fread(fid, 1,'*int32'); 0278 hist.smin = fread(fid, 1,'*int32'); 0279 0280 % check if hist.orient was saved as ascii char value 0281 switch hist.orient, 0282 case 48, hist.orient = uint8(0); 0283 case 49, hist.orient = uint8(1); 0284 case 50, hist.orient = uint8(2); 0285 case 51, hist.orient = uint8(3); 0286 case 52, hist.orient = uint8(4); 0287 case 53, hist.orient = uint8(5); 0288 end 0289 0290 return 0291 0292 0293 % Note on using char: 0294 % The 'char orient' field in the header is intended to 0295 % hold simply an 8-bit unsigned integer value, not the ASCII representation 0296 % of the character for that value. A single 'char' byte is often used to 0297 % represent an integer value in Analyze if the known value range doesn't 0298 % go beyond 0-255 - saves a byte over a short int, which may not mean 0299 % much in today's computing environments, but given that this format 0300 % has been around since the early 1980's, saving bytes here and there on 0301 % older systems was important! In this case, 'char' simply provides the 0302 % byte of storage - not an indicator of the format for what is stored in 0303 % this byte. Generally speaking, anytime a single 'char' is used, it is 0304 % probably meant to hold an 8-bit integer value, whereas if this has 0305 % been dimensioned as an array, then it is intended to hold an ASCII 0306 % character string, even if that was only a single character. 0307 % Denny <hanson.dennis2@mayo.edu> 0308 0309 0310 % Comments 0311 % The header format is flexible and can be extended for new 0312 % user-defined data types. The essential structures of the header 0313 % are the header_key and the image_dimension. 0314 % 0315 0316 % The required elements in the header_key substructure are: 0317 % 0318 % int sizeof_header Must indicate the byte size of the header file. 0319 % int extents Should be 16384, the image file is created as 0320 % contiguous with a minimum extent size. 0321 % char regular Must be 'r' to indicate that all images and 0322 % volumes are the same size. 0323 % 0324 0325 % The image_dimension substructure describes the organization and 0326 % size of the images. These elements enable the database to reference 0327 % images by volume and slice number. Explanation of each element follows: 0328 % 0329 % short int dim[ ]; /* Array of the image dimensions */ 0330 % 0331 % dim[0] Number of dimensions in database; usually 4. 0332 % dim[1] Image X dimension; number of pixels in an image row. 0333 % dim[2] Image Y dimension; number of pixel rows in slice. 0334 % dim[3] Volume Z dimension; number of slices in a volume. 0335 % dim[4] Time points; number of volumes in database. 0336 % dim[5] Undocumented. 0337 % dim[6] Undocumented. 0338 % dim[7] Undocumented. 0339 % 0340 % char vox_units[4] Specifies the spatial units of measure for a voxel. 0341 % char cal_units[8] Specifies the name of the calibration unit. 0342 % short int unused1 /* Unused */ 0343 % short int datatype /* Datatype for this image set */ 0344 % /*Acceptable values for datatype are*/ 0345 % #define DT_NONE 0 0346 % #define DT_UNKNOWN 0 /*Unknown data type*/ 0347 % #define DT_BINARY 1 /*Binary ( 1 bit per voxel)*/ 0348 % #define DT_UNSIGNED_CHAR 2 /*Unsigned character ( 8 bits per voxel)*/ 0349 % #define DT_SIGNED_SHORT 4 /*Signed short (16 bits per voxel)*/ 0350 % #define DT_SIGNED_INT 8 /*Signed integer (32 bits per voxel)*/ 0351 % #define DT_FLOAT 16 /*Floating point (32 bits per voxel)*/ 0352 % #define DT_COMPLEX 32 /*Complex (64 bits per voxel; 2 floating point numbers)/* 0353 % #define DT_DOUBLE 64 /*Double precision (64 bits per voxel)*/ 0354 % #define DT_RGB 128 /*A Red-Green-Blue datatype*/ 0355 % #define DT_ALL 255 /*Undocumented*/ 0356 % 0357 % short int bitpix; /* Number of bits per pixel; 1, 8, 16, 32, or 64. */ 0358 % short int dim_un0; /* Unused */ 0359 % 0360 % float pixdim[]; Parallel array to dim[], giving real world measurements in mm and ms. 0361 % pixdim[0]; Pixel dimensions? 0362 % pixdim[1]; Voxel width in mm. 0363 % pixdim[2]; Voxel height in mm. 0364 % pixdim[3]; Slice thickness in mm. 0365 % pixdim[4]; timeslice in ms (ie, TR in fMRI). 0366 % pixdim[5]; Undocumented. 0367 % pixdim[6]; Undocumented. 0368 % pixdim[7]; Undocumented. 0369 % 0370 % float vox_offset; Byte offset in the .img file at which voxels start. This value can be 0371 % negative to specify that the absolute value is applied for every image 0372 % in the file. 0373 % 0374 % float roi_scale; Specifies the Region Of Interest scale? 0375 % float funused1; Undocumented. 0376 % float funused2; Undocumented. 0377 % 0378 % float cal_max; Specifies the upper bound of the range of calibration values. 0379 % float cal_min; Specifies the lower bound of the range of calibration values. 0380 % 0381 % int compressed; Undocumented. 0382 % int verified; Undocumented. 0383 % 0384 % int glmax; The maximum pixel value for the entire database. 0385 % int glmin; The minimum pixel value for the entire database. 0386 % 0387 %