avw_hdr_read - read Analyze format data header (*.hdr) [ avw, machine ] = avw_hdr_read(fileprefix, [machine], [verbose]) 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. verbose - the default is to output processing information to the command window. If verbose = 0, this will not happen. 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, verbose) 0002 0003 % avw_hdr_read - read Analyze format data header (*.hdr) 0004 % 0005 % [ avw, machine ] = avw_hdr_read(fileprefix, [machine], [verbose]) 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 % verbose - the default is to output processing information to the command 0024 % window. If verbose = 0, this will not happen. 0025 % 0026 % This function is called by avw_img_read 0027 % 0028 % See also avw_hdr_write, avw_hdr_make, avw_view_hdr, avw_view 0029 % 0030 0031 % $Revision: 1.1 $ $Date: 2004/11/12 01:30:25 $ 0032 0033 % Licence: GNU GPL, no express or implied warranties 0034 % History: 05/2002, Darren.Weber@flinders.edu.au 0035 % The Analyze format and c code below is copyright 0036 % (c) Copyright, 1986-1995 0037 % Biomedical Imaging Resource, Mayo Foundation 0038 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0039 0040 if ~exist('verbose','var'), verbose = 1; end 0041 0042 if verbose, 0043 version = '[$Revision: 1.1 $]'; 0044 fprintf('\nAVW_HDR_READ [v%s]\n',version(12:16)); tic; 0045 end 0046 0047 if ~exist('fileprefix','var'), 0048 msg = sprintf('...no input fileprefix - see help avw_hdr_read\n\n'); 0049 error(msg); 0050 end 0051 if ~exist('machine','var'), machine = 'ieee-le'; end 0052 0053 0054 if findstr('.hdr',fileprefix), 0055 % fprintf('...removing .hdr extension from ''%s''\n',fileprefix); 0056 fileprefix = strrep(fileprefix,'.hdr',''); 0057 end 0058 if findstr('.img',fileprefix), 0059 % fprintf('...removing .img extension from ''%s''\n',fileprefix); 0060 fileprefix = strrep(fileprefix,'.img',''); 0061 end 0062 file = sprintf('%s.hdr',fileprefix); 0063 0064 if exist(file), 0065 if verbose, 0066 fprintf('...reading %s Analyze format',machine); 0067 end 0068 fid = fopen(file,'r',machine); 0069 avw.hdr = read_header(fid,verbose); 0070 avw.fileprefix = fileprefix; 0071 fclose(fid); 0072 0073 if ~isequal(avw.hdr.hk.sizeof_hdr,348), 0074 if verbose, fprintf('...failed.\n'); end 0075 % first try reading the opposite endian to 'machine' 0076 switch machine, 0077 case 'ieee-le', machine = 'ieee-be'; 0078 case 'ieee-be', machine = 'ieee-le'; 0079 end 0080 if verbose, fprintf('...reading %s Analyze format',machine); end 0081 fid = fopen(file,'r',machine); 0082 avw.hdr = read_header(fid,verbose); 0083 avw.fileprefix = fileprefix; 0084 fclose(fid); 0085 end 0086 if ~isequal(avw.hdr.hk.sizeof_hdr,348), 0087 % Now throw an error 0088 if verbose, fprintf('...failed.\n'); end 0089 msg = sprintf('...size of header not equal to 348 bytes!\n\n'); 0090 error(msg); 0091 end 0092 else 0093 msg = sprintf('...cannot find file %s.hdr\n\n',file); 0094 error(msg); 0095 end 0096 0097 if verbose, 0098 t=toc; fprintf('...done (%5.2f sec).\n',t); 0099 end 0100 0101 return 0102 0103 0104 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0105 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0106 function [ dsr ] = read_header(fid,verbose) 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,verbose); 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,verbose) 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 if verbose, 0224 fprintf('...ensuring 4 dimensions in avw.hdr.dime.dim\n'); 0225 end 0226 dime.dim(1) = int16(4); 0227 end 0228 if dime.dim(5) < 1, % Time points; number of volumes in database 0229 if verbose, 0230 fprintf('...ensuring at least 1 volume in avw.hdr.dime.dim(5)\n'); 0231 end 0232 dime.dim(5) = int16(1); 0233 end 0234 0235 return 0236 0237 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0238 function [ hist ] = data_history(fid) 0239 0240 % Original header structures - ANALYZE 7.5 0241 %struct data_history 0242 % { /* off + size */ 0243 % char descrip[80]; /* 0 + 80 */ 0244 % char aux_file[24]; /* 80 + 24 */ 0245 % char orient; /* 104 + 1 */ 0246 % char originator[10]; /* 105 + 10 */ 0247 % char generated[10]; /* 115 + 10 */ 0248 % char scannum[10]; /* 125 + 10 */ 0249 % char patient_id[10]; /* 135 + 10 */ 0250 % char exp_date[10]; /* 145 + 10 */ 0251 % char exp_time[10]; /* 155 + 10 */ 0252 % char hist_un0[3]; /* 165 + 3 */ 0253 % int views /* 168 + 4 */ 0254 % int vols_added; /* 172 + 4 */ 0255 % int start_field; /* 176 + 4 */ 0256 % int field_skip; /* 180 + 4 */ 0257 % int omax; /* 184 + 4 */ 0258 % int omin; /* 188 + 4 */ 0259 % int smax; /* 192 + 4 */ 0260 % int smin; /* 196 + 4 */ 0261 % }; /* total=200 bytes */ 0262 0263 hist.descrip = fread(fid,80,'*char')'; 0264 hist.aux_file = fread(fid,24,'*char')'; 0265 hist.orient = fread(fid, 1,'*uint8'); % see note below on char 0266 hist.originator = fread(fid,10,'*char')'; 0267 hist.generated = fread(fid,10,'*char')'; 0268 hist.scannum = fread(fid,10,'*char')'; 0269 hist.patient_id = fread(fid,10,'*char')'; 0270 hist.exp_date = fread(fid,10,'*char')'; 0271 hist.exp_time = fread(fid,10,'*char')'; 0272 hist.hist_un0 = fread(fid, 3,'*char')'; 0273 hist.views = fread(fid, 1,'*int32'); 0274 hist.vols_added = fread(fid, 1,'*int32'); 0275 hist.start_field = fread(fid, 1,'*int32'); 0276 hist.field_skip = fread(fid, 1,'*int32'); 0277 hist.omax = fread(fid, 1,'*int32'); 0278 hist.omin = fread(fid, 1,'*int32'); 0279 hist.smax = fread(fid, 1,'*int32'); 0280 hist.smin = fread(fid, 1,'*int32'); 0281 0282 % check if hist.orient was saved as ascii char value 0283 switch hist.orient, 0284 case 48, hist.orient = uint8(0); 0285 case 49, hist.orient = uint8(1); 0286 case 50, hist.orient = uint8(2); 0287 case 51, hist.orient = uint8(3); 0288 case 52, hist.orient = uint8(4); 0289 case 53, hist.orient = uint8(5); 0290 end 0291 0292 return 0293 0294 0295 % Note on using char: 0296 % The 'char orient' field in the header is intended to 0297 % hold simply an 8-bit unsigned integer value, not the ASCII representation 0298 % of the character for that value. A single 'char' byte is often used to 0299 % represent an integer value in Analyze if the known value range doesn't 0300 % go beyond 0-255 - saves a byte over a short int, which may not mean 0301 % much in today's computing environments, but given that this format 0302 % has been around since the early 1980's, saving bytes here and there on 0303 % older systems was important! In this case, 'char' simply provides the 0304 % byte of storage - not an indicator of the format for what is stored in 0305 % this byte. Generally speaking, anytime a single 'char' is used, it is 0306 % probably meant to hold an 8-bit integer value, whereas if this has 0307 % been dimensioned as an array, then it is intended to hold an ASCII 0308 % character string, even if that was only a single character. 0309 % Denny <hanson.dennis2@mayo.edu> 0310 0311 0312 % Comments 0313 % The header format is flexible and can be extended for new 0314 % user-defined data types. The essential structures of the header 0315 % are the header_key and the image_dimension. 0316 % 0317 0318 % The required elements in the header_key substructure are: 0319 % 0320 % int sizeof_header Must indicate the byte size of the header file. 0321 % int extents Should be 16384, the image file is created as 0322 % contiguous with a minimum extent size. 0323 % char regular Must be 'r' to indicate that all images and 0324 % volumes are the same size. 0325 % 0326 0327 % The image_dimension substructure describes the organization and 0328 % size of the images. These elements enable the database to reference 0329 % images by volume and slice number. Explanation of each element follows: 0330 % 0331 % short int dim[ ]; /* Array of the image dimensions */ 0332 % 0333 % dim[0] Number of dimensions in database; usually 4. 0334 % dim[1] Image X dimension; number of pixels in an image row. 0335 % dim[2] Image Y dimension; number of pixel rows in slice. 0336 % dim[3] Volume Z dimension; number of slices in a volume. 0337 % dim[4] Time points; number of volumes in database. 0338 % dim[5] Undocumented. 0339 % dim[6] Undocumented. 0340 % dim[7] Undocumented. 0341 % 0342 % char vox_units[4] Specifies the spatial units of measure for a voxel. 0343 % char cal_units[8] Specifies the name of the calibration unit. 0344 % short int unused1 /* Unused */ 0345 % short int datatype /* Datatype for this image set */ 0346 % /*Acceptable values for datatype are*/ 0347 % #define DT_NONE 0 0348 % #define DT_UNKNOWN 0 /*Unknown data type*/ 0349 % #define DT_BINARY 1 /*Binary ( 1 bit per voxel)*/ 0350 % #define DT_UNSIGNED_CHAR 2 /*Unsigned character ( 8 bits per voxel)*/ 0351 % #define DT_SIGNED_SHORT 4 /*Signed short (16 bits per voxel)*/ 0352 % #define DT_SIGNED_INT 8 /*Signed integer (32 bits per voxel)*/ 0353 % #define DT_FLOAT 16 /*Floating point (32 bits per voxel)*/ 0354 % #define DT_COMPLEX 32 /*Complex (64 bits per voxel; 2 floating point numbers)/* 0355 % #define DT_DOUBLE 64 /*Double precision (64 bits per voxel)*/ 0356 % #define DT_RGB 128 /*A Red-Green-Blue datatype*/ 0357 % #define DT_ALL 255 /*Undocumented*/ 0358 % 0359 % short int bitpix; /* Number of bits per pixel; 1, 8, 16, 32, or 64. */ 0360 % short int dim_un0; /* Unused */ 0361 % 0362 % float pixdim[]; Parallel array to dim[], giving real world measurements in mm and ms. 0363 % pixdim[0]; Pixel dimensions? 0364 % pixdim[1]; Voxel width in mm. 0365 % pixdim[2]; Voxel height in mm. 0366 % pixdim[3]; Slice thickness in mm. 0367 % pixdim[4]; timeslice in ms (ie, TR in fMRI). 0368 % pixdim[5]; Undocumented. 0369 % pixdim[6]; Undocumented. 0370 % pixdim[7]; Undocumented. 0371 % 0372 % float vox_offset; Byte offset in the .img file at which voxels start. This value can be 0373 % negative to specify that the absolute value is applied for every image 0374 % in the file. 0375 % 0376 % float roi_scale; Specifies the Region Of Interest scale? 0377 % float funused1; Undocumented. 0378 % float funused2; Undocumented. 0379 % 0380 % float cal_max; Specifies the upper bound of the range of calibration values. 0381 % float cal_min; Specifies the lower bound of the range of calibration values. 0382 % 0383 % int compressed; Undocumented. 0384 % int verified; Undocumented. 0385 % 0386 % int glmax; The maximum pixel value for the entire database. 0387 % int glmin; The minimum pixel value for the entire database. 0388 % 0389 %