Mercurial > hg > octave-image
changeset 611:9994e96e9ade
analyze75: code clean to follow standards, simpler code, checks, more documentation, and move of common code to shared subfunctions
author | carandraug |
---|---|
date | Tue, 25 Sep 2012 17:21:39 +0000 |
parents | 4c92bffbf4cc |
children | 7c1df1b5f058 |
files | inst/analyze75info.m inst/analyze75read.m inst/private/analyze75filename.m |
diffstat | 3 files changed, 195 insertions(+), 244 deletions(-) [+] |
line wrap: on
line diff
--- a/inst/analyze75info.m +++ b/inst/analyze75info.m @@ -1,4 +1,5 @@ %% Copyright (C) 2012 Adam H Aitkenhead <adamaitkenhead@hotmail.com> +%% Copyright (C) 2012 Carnë Draug <carandraug+dev@gmail.com> %% %% This program is free software; you can redistribute it and/or modify %% it under the terms of the GNU General Public License as published by @@ -14,182 +15,126 @@ %% along with this program; If not, see <http://www.gnu.org/licenses/>. %% -*- texinfo -*- -%% @deftypefn {Function File} {@var{header} = } analyze75info(@var{filename}) -%% Read the header of an Analyze file. +%% @deftypefn {Function File} {@var{header} =} analyze75info (@var{filename}) +%% @deftypefnx {Function File} {@var{header} =} analyze75info (@var{filename}, "ByteOrder", @var{arch}) +%% Read header of an Analyze 7.5 file. +%% +%% @var{filename} must be the path for an Analyze 7.5 file or the path for a +%% directory with a single .hdr file can be specified. %% -%% FILENAME is a string (giving the filename). +%% The optional argument @code{"ByteOrder"} reads the file with the specified +%% @var{arch} ("ieee-be" or "ieee-le" for IEEE big endian or IEEE +%% little endian respectively). +%% +%% @var{header} is a structure with the file information. +%% +%% @seealso{analyze75read} %% @end deftypefn -function header = analyze75info(varargin); -%-------------------------------------------------------------------------- - -%-------------- -% Check filename -%-------------- - -filename = varargin{1}; - -if exist('filename','var')==1 && exist(filename,'dir')==7 - filelist = dir([filename,filesep,'*.hdr']); - if numel(filelist)==1 - filename = [filename,filesep,filelist.name]; - else - [filename,filepath] = uigetfile([filename,filesep,'*.hdr'],'Select the input file'); - filename = [filepath,filename]; - end -elseif ( exist('filename','var')==1 && exist(filename,'file')==0 ) || exist('filename','var')==0 - [filename,filepath] = uigetfile('*.hdr','Select the input file'); - filename = [filepath,filename]; -end - -% Strip the filename of the extension +function header = analyze75info (filename, varargin) -fileextH = strfind(filename,'.hdr'); -fileextI = strfind(filename,'.img'); -if isempty(fileextH)==0 - fileprefix = filename(1:fileextH-1); -elseif isempty(fileextI)==0 - fileprefix = filename(1:fileextI-1); -else - fileprefix = filename; -end - -%-------------- -% Check the byteorder -%-------------- - -byteorder = 'ieee-le'; - -for loopN = 2:nargin-1 - if ischar(varargin{loopN}) && strcmpi(varargin{loopN})=='ByteOrder' - if ischar(varargin{loopN+1}) && ( strcmpi(varargin{loopN+1})=='ieee-be' || strcmpi(varargin{loopN+1})=='b' ) - byteorder = 'ieee-be'; - disp('Code does not yet work for big-endian files.') - else - byteorder = 'ieee-le'; + if (nargin ~= 1 && nargin ~= 3) + print_usage; + elseif (~ischar (filename)) + error ('analyze75info: `filename'' must be a string'); + elseif (nargin == 3) + %% Check the byteorder + if (strcmpi (varargin{1}, 'byteorder')) + error ('analyze75info: second argument must be string `ByteOrder'''); + elseif (!all (strcmpi (varargin{3}, {'ieee-le', 'l', 'ieee-be', 'b'}))) + error ('analyze75info: valid options for `ByteOrder'' are `ieee-le'' or `ieee-be'''); + elseif (any (strcmpi (varargin{3}, {'ieee-be', 'b'}))) + warning ('analyze75info: no support for big-endian. Please consider submitting a patch. Attempting to read as little-endian'); end end -end + + fileprefix = analyze75filename (filename); -%-------------- -% Read the file -%-------------- + %% finally start reading the actual file + hdrdirdata = dir ([fileprefix, '.hdr']); + imgdirdata = dir ([fileprefix, '.img']); -header = READ_hdr(fileprefix); - + header.ImgFileSize = imgdirdata.bytes; -end %function -%-------------------------------------------------------------------------- - + header.Filename = [fileprefix, '.hdr']; + header.FileModDate = hdrdirdata.date; + header.Format = 'Analyze'; + header.FormatVersion = '7.5'; + header.ColorType = 'grayscale'; + header.ByteOrder = 'ieee-le'; -%-------------------------------------------------------------------------- -function [header] = READ_hdr(fileprefix) - -%---------------------------- -% Gather the header info -%---------------------------- - -dirdata = dir([fileprefix,'.hdr']); + fidH = fopen ([fileprefix, '.hdr']); -header.Filename = [fileprefix,'.hdr']; -header.FileModDate = dirdata.date; -header.Format = 'Analyze'; -header.FormatVersion = '7.5'; -header.ColorType = 'grayscale'; -header.ByteOrder = 'ieee-le'; - -fidH = fopen([fileprefix,'.hdr']); - -header.HdrFileSize = fread(fidH,1,'int32'); -header.HdrDataType = char(fread(fidH,10,'char'))'; -header.DatabaseName = char(fread(fidH,18,'char'))'; -header.Extents = fread(fidH,1,'int32'); -header.SessionError = fread(fidH,1,'int16'); -header.Regular = char(fread(fidH,1,'char')); -unused = char(fread(fidH,1,'char')); -unused = fread(fidH,1,'int16'); -header.Dimensions = zeros(size(1,4)); -header.Dimensions(1) = fread(fidH,1,'int16'); -header.Dimensions(2) = fread(fidH,1,'int16'); -header.Dimensions(3) = fread(fidH,1,'int16'); -header.Dimensions(4) = fread(fidH,1,'int16'); -unused = fread(fidH,3,'int16'); -header.VoxelUnits = char(fread(fidH,4,'char'))'; -header.CalibrationUnits = char(fread(fidH,8,'char'))'; -unused = fread(fidH,1,'int16'); + header.HdrFileSize = fread (fidH, 1, 'int32'); + header.HdrDataType = char (fread (fidH, 10, 'char'))'; + header.DatabaseName = char (fread (fidH, 18, 'char'))'; + header.Extents = fread (fidH, 1, 'int32'); + header.SessionError = fread (fidH, 1, 'int16'); + header.Regular = char (fread (fidH, 1, 'char')); + unused = char (fread (fidH, 1, 'char')); + unused = fread (fidH, 1, 'int16'); + header.Dimensions = zeros (size (1, 4)); + header.Dimensions(1) = fread (fidH, 1, 'int16'); + header.Dimensions(2) = fread (fidH, 1, 'int16'); + header.Dimensions(3) = fread (fidH, 1, 'int16'); + header.Dimensions(4) = fread (fidH, 1, 'int16'); + unused = fread (fidH, 3, 'int16'); + header.VoxelUnits = char (fread (fidH, 4, 'char'))'; + header.CalibrationUnits = char (fread (fidH, 8, 'char'))'; + unused = fread (fidH, 1, 'int16'); -datatype = fread(fidH,1,'int16'); -if datatype==0 - header.ImgDataType = 'DT_UNKNOWN'; -elseif datatype==1 - header.ImgDataType = 'DT_BINARY'; -elseif datatype==2 - header.ImgDataType = 'DT_UNSIGNED_CHAR'; -elseif datatype==4 - header.ImgDataType = 'DT_SIGNED_SHORT'; -elseif datatype==8 - header.ImgDataType = 'DT_SIGNED_INT'; -elseif datatype==16 - header.ImgDataType = 'DT_FLOAT'; -elseif datatype==32 - header.ImgDataType = 'DT_COMPLEX'; -elseif datatype==64 - header.ImgDataType = 'DT_DOUBLE'; -elseif datatype==128 - header.ImgDataType = 'DT_RGB'; -elseif datatype==255 - header.ImgDataType = 'DT_ALL'; -end + datatype = fread (fidH, 1, 'int16'); + switch datatype + case 0, header.ImgDataType = 'DT_UNKNOWN'; + case 1, header.ImgDataType = 'DT_BINARY'; + case 2, header.ImgDataType = 'DT_UNSIGNED_CHAR'; + case 4, header.ImgDataType = 'DT_SIGNED_SHORT'; + case 8, header.ImgDataType = 'DT_SIGNED_INT'; + case 16, header.ImgDataType = 'DT_FLOAT'; + case 32, header.ImgDataType = 'DT_COMPLEX'; + case 64, header.ImgDataType = 'DT_DOUBLE'; + case 128, header.ImgDataType = 'DT_RGB'; + case 255, header.ImgDataType = 'DT_ALL'; + otherwise, warning ('analyze75: unable to detect ImgDataType'); + end -header.BitDepth = fread(fidH,1,'int16'); -unused = fread(fidH,1,'int16'); -unused = fread(fidH,1,'float'); -header.PixelDimensions = zeros(1,3); -header.PixelDimensions(1) = fread(fidH,1,'float'); -header.PixelDimensions(2) = fread(fidH,1,'float'); -header.PixelDimensions(3) = fread(fidH,1,'float'); -unused = fread(fidH,4,'float'); -header.VoxelOffset = fread(fidH,1,'float'); -unused = fread(fidH,3,'float'); -header.CalibrationMax = fread(fidH,1,'float'); -header.CalibrationMin = fread(fidH,1,'float'); -header.Compressed = fread(fidH,1,'float'); -header.Verified = fread(fidH,1,'float'); -header.GlobalMax = fread(fidH,1,'int32'); -header.GlobalMin = fread(fidH,1,'int32'); -header.Descriptor = char(fread(fidH,80,'char'))'; -header.AuxFile = char(fread(fidH,24,'char'))'; -header.Orientation = char(fread(fidH,1,'char'))'; -header.Originator = char(fread(fidH,10,'char'))'; -header.Generated = char(fread(fidH,10,'char'))'; -header.Scannumber = char(fread(fidH,10,'char'))'; -header.PatientID = char(fread(fidH,10,'char'))'; -header.ExposureDate = char(fread(fidH,10,'char'))'; -header.ExposureTime = char(fread(fidH,10,'char'))'; -unused = char(fread(fidH,3,'char'))'; -header.Views = fread(fidH,1,'int32'); -header.VolumesAdded = fread(fidH,1,'int32'); -header.StartField = fread(fidH,1,'int32'); -header.FieldSkip = fread(fidH,1,'int32'); -header.OMax = fread(fidH,1,'int32'); -header.OMin = fread(fidH,1,'int32'); -header.SMax = fread(fidH,1,'int32'); -header.SMin = fread(fidH,1,'int32'); + header.BitDepth = fread (fidH, 1, 'int16'); + unused = fread (fidH, 1, 'int16'); + unused = fread (fidH, 1, 'float'); + header.PixelDimensions = zeros (1, 3); + header.PixelDimensions(1) = fread (fidH, 1, 'float'); + header.PixelDimensions(2) = fread (fidH, 1, 'float'); + header.PixelDimensions(3) = fread (fidH, 1, 'float'); + unused = fread (fidH, 4, 'float'); + header.VoxelOffset = fread (fidH, 1, 'float'); + unused = fread (fidH, 3, 'float'); + header.CalibrationMax = fread (fidH, 1, 'float'); + header.CalibrationMin = fread (fidH, 1, 'float'); + header.Compressed = fread (fidH, 1, 'float'); + header.Verified = fread (fidH, 1, 'float'); + header.GlobalMax = fread (fidH, 1, 'int32'); + header.GlobalMin = fread (fidH, 1, 'int32'); + header.Descriptor = char (fread (fidH, 80, 'char'))'; + header.AuxFile = char (fread (fidH, 24, 'char'))'; + header.Orientation = char (fread (fidH, 1, 'char'))'; + header.Originator = char (fread (fidH, 10, 'char'))'; + header.Generated = char (fread (fidH, 10, 'char'))'; + header.Scannumber = char (fread (fidH, 10, 'char'))'; + header.PatientID = char (fread (fidH, 10, 'char'))'; + header.ExposureDate = char (fread (fidH, 10, 'char'))'; + header.ExposureTime = char (fread (fidH, 10, 'char'))'; + unused = char (fread (fidH, 3, 'char'))'; + header.Views = fread (fidH, 1, 'int32'); + header.VolumesAdded = fread (fidH, 1, 'int32'); + header.StartField = fread (fidH, 1, 'int32'); + header.FieldSkip = fread (fidH, 1, 'int32'); + header.OMax = fread (fidH, 1, 'int32'); + header.OMin = fread (fidH, 1, 'int32'); + header.SMax = fread (fidH, 1, 'int32'); + header.SMin = fread (fidH, 1, 'int32'); -header.Width = header.Dimensions(1); -header.Height = header.Dimensions(2); - -fclose(fidH); - -%---------------------------- -% Check the img filesize -%---------------------------- + header.Width = header.Dimensions(1); + header.Height = header.Dimensions(2); -fidI = fopen([fileprefix,'.img']); -fseek(fidI,0,1); -header.ImgFileSize = ftell(fidI); -fclose(fidI); - -end %function -%-------------------------------------------------------------------------- - + fclose(fidH); +end
--- a/inst/analyze75read.m +++ b/inst/analyze75read.m @@ -1,4 +1,5 @@ %% Copyright (C) 2012 Adam H Aitkenhead <adamaitkenhead@hotmail.com> +%% Copyright (C) 2012 Carnë Draug <carandraug+dev@gmail.com> %% %% This program is free software; you can redistribute it and/or modify %% it under the terms of the GNU General Public License as published by @@ -14,95 +15,55 @@ %% along with this program; If not, see <http://www.gnu.org/licenses/>. %% -*- texinfo -*- -%% @deftypefn {Function File} {@var{image} = } analyze75read(@var{filename}) -%% @deftypefnx {Function File} {@var{image} = } analyze75read(@var{structure}) -%% Read the image data contained in an Analyze file. +%% @deftypefn {Function File} {@var{image} =} analyze75read (@var{filename}) +%% @deftypefnx {Function File} {@var{image} =} analyze75read (@var{header}) +%% Read image data of an Analyze 7.5 file. %% -%% FILENAME is a string (giving the filename). -%% Alternatively, STRUCTURE is a structure containing a field `Filename' -%% (such as returned by `analyze75info'). +%% @var{filename} must be the path for an Analyze 7.5 file or the path for a +%% directory with a single .hdr file can be specified. Alternatively, the file +%% @var{header} can be specified as returned by @code{analyze75info}. +%% +%% @seealso{analyze75info} %% @end deftypefn -function data = analyze75read(varargin); -%-------------------------------------------------------------------------- - -%-------------- -% Check filename -%-------------- - -filename = varargin{1}; +function data = analyze75read (filename); -if isstruct(filename)==1 && isfield(filename,'Filename')==1 - header = filename; - filename = header.Filename; -elseif exist('filename','var')==1 && exist(filename,'dir')==7 - filelist = dir([filename,filesep,'*.hdr']); - if numel(filelist)==1 - filename = [filename,filesep,filelist.name]; - else - [filename,filepath] = uigetfile([filename,filesep,'*.hdr'],'Select the input file'); - filename = [filepath,filename]; + if (nargin ~= 1) + print_usage; + elseif (isstruct (filename)) + if (~isfield (filename, 'Filename')) + error ('analyze75read: structure given does not have a `Filename'' field.'); + else + header = filename; + filename = filename.Filename; + end + elseif (~ischar (filename)) + error ('analyze75read: `filename'' must be either a string or a structure.'); end -elseif ( exist('filename','var')==1 && exist(filename,'file')==0 ) || exist('filename','var')==0 - [filename,filepath] = uigetfile('*.hdr','Select the input file'); - filename = [filepath,filename]; -end -% Strip the filename of the extension + fileprefix = analyze75filename (filename); -fileextH = strfind(filename,'.hdr'); -fileextI = strfind(filename,'.img'); -if isempty(fileextH)==0 - fileprefix = filename(1:fileextH-1); -elseif isempty(fileextI)==0 - fileprefix = filename(1:fileextI-1); -else - fileprefix = filename; -end - -%-------------- -% Read the file -%-------------- + if (~exist ('header', 'var')) + header = analyze75info ([fileprefix, '.hdr']); + end -if exist('header','var')==0 - header = analyze75info(filename); -end - -data = READ_img(fileprefix,header); - -end %function -%-------------------------------------------------------------------------- - - -%-------------------------------------------------------------------------- -function [data] = READ_img(fileprefix,header) - -%---------------------------- -% Read the .img file -%---------------------------- - -fidI = fopen([fileprefix,'.img']); - -fseek(fidI,0,-1); + %% finally start reading the actual file + [fidI, err] = fopen ([fileprefix, '.img']); + if (fidI < 0) + error ('analyze75read: unable to fopen `%s'': %s', [fileprefix, '.img'], err); + end -if strcmp(header.ImgDataType,'DT_FLOAT')==1 - datatype = 'single'; -else - datatype = 'double'; -end - -data = zeros(header.Dimensions,datatype); -data(:) = fread(fidI,datatype,header.ByteOrder); - -fclose(fidI); + if (strcmp (header.ImgDataType, 'DT_FLOAT')) + datatype = 'single'; + else + datatype = 'double'; + end -%---------------------------- -% Rearrange the data -%---------------------------- + data = zeros (header.Dimensions, datatype); + data(:) = fread (fidI, datatype, header.ByteOrder); -data = permute(data,[2,1,3]); + fclose (fidI); -end %function -%-------------------------------------------------------------------------- - - + %% Rearrange the data + data = permute (data, [2,1,3]); +end
new file mode 100644 --- /dev/null +++ b/inst/private/analyze75filename.m @@ -0,0 +1,45 @@ +%% Copyright (C) 2012 Adam H Aitkenhead <adamaitkenhead@hotmail.com> +%% Copyright (C) 2012 Carnë Draug <carandraug+dev@gmail.com> +%% +%% This program is free software; you can redistribute it and/or modify +%% it under the terms of the GNU General Public License as published by +%% the Free Software Foundation; either version 3 of the License, or +%% (at your option) any later version. +%% +%% This program is distributed in the hope that it will be useful, +%% but WITHOUT ANY WARRANTY; without even the implied warranty of +%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +%% GNU General Public License for more details. +%% +%% You should have received a copy of the GNU General Public License +%% along with this program; If not, see <http://www.gnu.org/licenses/>. + +%% private function with common code for the analyze75info and read functions + +function filename = analyze75check (filename) + + %% Check filename + if (exist (filename, 'dir')) + filelist = dir ([filename, filesep, '*.hdr']); + if (numel (filelist) == 1) + filename = [filename, filesep, filelist.name]; + elseif (numel (filelist) > 1) + error ('analyze75: `filename'' is a directory with multiple hdr files.') + else + error ('analyze75: `filename'' is a directory with no hdr files.') + end + elseif (~exist (filename,'file') + error ('analyze75info: no file `%s''', filename) + end + + %% Strip the filename of the extension + fileextH = strfind (filename, '.hdr'); + fileextI = strfind (filename, '.img'); + if (~isempty (fileextH)) + filename = filename(1:fileextH(end)-1); + elseif (~isempty (fileextI)) + filename = filename(1:fileextI(end)-1); + else + filename = filename; + end +end