Code covered by the BSD License  

Highlights from
DICOM debug utility

image thumbnail
from DICOM debug utility by Jeff Mather
A tool to dump the contents of DICOM files for debugging

dicomdump(msgname, varargin)
function dicomdump(msgname, varargin)
%DICOMDUMP  Read metadata from DICOM message.
%   DICOMDUMP(FILENAME) reads the metadata from the compliant
%   DICOM file specified in the string FILENAME and prints it.
%
%   DICOMDUMP(FILENAME, 'dictionary', D) uses the data dictionary
%   file given in the string D to read the DICOM file.  The file in
%   D must be on the MATLAB search path.  The default value is
%   dicom-dict.mat.
%
%   Example:
%
%     info = dicomdump('CT-MONO2-16-ankle.dcm');
%
%   See also DICOMDICT, DICOMINFO, DICOMREAD, DICOMWRITE, DICOMUID.

% Author: Jeff Mather
% Copyright 2006-2007 The MathWorks, Inc.
% $Revision: 1.1.2.4 $  $Date: 2007/09/26 15:01:04 $

% This function (along with DICOMREAD) implements the M-READ service.
% This function implements the M-INQUIRE FILE service.


% Parse input arguments.
if (nargin < 1)
    eid = 'Images:dicomdump:tooFewInputs';
    error(eid, '%s', 'DICOMDUMP requires at least one argument.')
    
end

% Set the dictionary.
args = parse_inputs(varargin{:});
dicomdict('set_current', args.Dictionary)

% Get the info.
try

    if (isdicom(msgname))
        get_info(msgname, varargin{:});
    else
        error('Images:dicomdump:notDICOM', ...
              'The specified file is not in DICOM format.')
    end
    
catch
    
    dicomdict('reset_current');
    rethrow(lasterror)
    
end

% Reset the dictionary.
dicomdict('reset_current');



function get_info(filename, varargin)

% Get details about the file to read.
d = dir(filename);

if (isempty(d))

  fid = fopen(filename);

  if (fid < 0)
    
    error('Images:dicomdump:fileNotFound', ...
          'File "%s" not found.', filename);
    
  end

  filename = fopen(fid);
  d = dir(filename);
  d.name = filename;
  fclose(fid);

else
  
  d.name = filename;
  
end

% Parse the DICOM file.
attrs = dicomparse(d.name, d.bytes, getEndian, false, dicomdict('get'));

printFileDetails(d, attrs);
printHeader();
printAttributes(attrs, 0);



function printFileDetails(fileDetails, attrs)

% File and platform details.
disp(sprintf('File: %s (%d bytes)', ...
             fileDetails.name, fileDetails.bytes))
if (isequal(getEndian, 'L'))
    disp('Read on an IEEE little-endian machine.')
else
    disp('Read on an IEEE big-endian machine.')
end

% Conformance and encoding details
if (attrs(1).Group == 2)
  
    % It has proper file transfer metadata.
    disp(sprintf('File begins with group 0002 metadata at byte %d.', ...
         attrs(1).Location))
    
    % Report about the transfer syntax (0002,0010).
    idx = find(([attrs(:).Group] == 2) & ([attrs(:).Element] == 16));
    if (~isempty(idx))
        txfr = deblank(char(attrs(idx).Data));
        txfr(txfr == 0) = '';
        uidDetails = dicom_uid_decode(txfr);
        disp(sprintf('Transfer syntax: %s (%s).', txfr, uidDetails.Name))
    else
        disp('Transfer syntax not present.')
    end
    
else
  
    disp('File does not have group 0002 attributes.')
    
end

% What kind of DICOM file is it?  Attribute (0008,0016) says.
idx = find(([attrs(:).Group] == 8) & ([attrs(:).Element] == 22));
if (~isempty(idx))

    SOPClassUID = deblank(char(attrs(idx).Data));
    SOPClassUID(SOPClassUID == 0) = '';
    uidDetails = dicom_uid_decode(SOPClassUID);
    disp(sprintf('DICOM Information object: %s (%s).', ...
                 SOPClassUID, uidDetails.Name));
    
else
  
    disp('SOP Class UID attribute (0008,0016) not present.  Unknown type.')
    
end

% Print a blank line.
disp(' ')



function printHeader

disp(sprintf('Location  Lvl     Tag     VR         Size       %-32s Data', 'Name'))
disp(repmat('-', [1 100]))



function printAttributes(attrs, level)
% Dump the DICOM attributes.

for currentAttr = 1:numel(attrs)
  
  % Find this attribute.
  this = attrs(currentAttr);
  
  % Get the VR.
  if (isempty(this.VR))
    this.VR = '""';
  end
  
  % Get a printable version of the attribute's data.
  if (isempty(this.Data))
    data = '[]';

  elseif (isstruct(this.Data))
    printOne(this, '', level)
    printAttributes(this.Data, level + 1);
    continue
    
  elseif (any(this.Data(1:end-1) < 32) || any(this.Data > 126))
    data = '*Binary*';
    
  else
    data = sprintf('[%s]', char(this.Data));
    
  end

  printOne(this, data, level)
  
end



function printOne(attr, data, level)

% Display the attribute.
disp(sprintf('%07d  %3d  (%04X,%04X) %2s %10.0f bytes - %-32s %s', ...
             attr.Location, ...
             level, ...
             attr.Group, ...
             attr.Element, ...
             attr.VR, ...
             attr.Length, ...
             dicomlookup_actions(attr.Group, attr.Element), ...
             data))
  


function byteOrder = getEndian

persistent endian

if (~isempty(endian))
  byteOrder = endian;
  return
end

[c, m, endian] = computer;
byteOrder = endian;



function args = parse_inputs(varargin)

% Set default values
args.Dictionary = dicomdict('get');

% Parse arguments based on their number.
if (nargin > 1)
    
    paramStrings = {'dictionary'};
    
    % For each pair
    for k = 1:2:length(varargin)
       param = lower(varargin{k});
       
            
       if (~ischar(param))
           eid = 'Images:dicomdump:parameterNameNotString';
           msg = 'Parameter name must be a string';
           error(eid, '%s', msg);
       end

       idx = strmatch(param, paramStrings);
       
       if (isempty(idx))
           eid = 'Images:dicomdump:unrecognizedParameterName';
           msg = sprintf('Unrecognized parameter name "%s"', param);
           error(eid, '%s', msg);
       elseif (length(idx) > 1)
           eid = 'Images:dicomdump:ambiguousParameterName';
           msg = sprintf('Ambiguous parameter name "%s"', param);
           error(eid, '%s', msg);
       end
    
       switch (paramStrings{idx})
       case 'dictionary'

           if (k == length(varargin))
               eid = 'Images:dicomdump:missingDictionary';
               msg = 'No data dictionary specified.';
               error(eid, '%s', msg);
           else
               args.Dictionary = varargin{k + 1};
           end

       end  % switch
       
    end  % for
           
end

Contact us at files@mathworks.com