summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafael Laboissière <rafael@debian.org>2022-07-08 09:28:26 -0300
committerRafael Laboissière <rafael@debian.org>2022-07-08 09:28:26 -0300
commit4c9af98998a4e914ce7562c3abe7402c0765c89f (patch)
tree778d69b7025ec867d04db830b98990eb20b20971
parent5bf4f2ed5986cc4819d61b716eea4417fe073185 (diff)
parent04a4e459f804652334fcbbe923b9e433090a628d (diff)
Merge tag 'upstream/0.5.0' into debian/latest
Upstream version 0.5.0
-rw-r--r--DESCRIPTION6
-rw-r--r--INDEX2
-rw-r--r--NEWS9
-rw-r--r--doc/dicom.pdfbin309339 -> 316802 bytes
-rw-r--r--doc/dicom.texi5
-rw-r--r--doc/functions.texi240
-rw-r--r--inst/dicomfind.m111
-rw-r--r--inst/dicomupdate.m141
-rw-r--r--inst/imdata/CT-MONO2-16-ankle.dcmbin0 -> 525436 bytes
-rw-r--r--inst/imdata/README.md2
-rw-r--r--inst/imdata/US-PAL-8-10x-echo.dcmbin0 -> 483610 bytes
-rw-r--r--inst/imdata/rtstruct.dcmbin0 -> 134254 bytes
-rw-r--r--inst/imdata/simple-test.dcmbin0 -> 1554 bytes
-rw-r--r--inst/imdata/simpleImageWithIcon.dcmbin0 -> 33862 bytes
-rw-r--r--src/config.h.in3
-rwxr-xr-xsrc/configure826
-rw-r--r--src/configure.ac23
-rw-r--r--src/dicomanon.cpp3
-rw-r--r--src/dicomdict.cpp21
-rw-r--r--src/dicomdisp.cpp6
-rw-r--r--src/dicominfo.cpp67
-rw-r--r--src/dicomlookup.cpp25
-rw-r--r--src/dicomread.cpp43
-rw-r--r--src/dicomuid.cpp11
-rw-r--r--src/dicomwrite.cpp24
-rw-r--r--src/isdicom.cpp18
26 files changed, 1142 insertions, 444 deletions
diff --git a/DESCRIPTION b/DESCRIPTION
index 998ebbc..b51c9b1 100644
--- a/DESCRIPTION
+++ b/DESCRIPTION
@@ -1,8 +1,8 @@
Name: dicom
-Version: 0.4.1
-Date: 2022-02-22
+Version: 0.5.0
+Date: 2022-06-30
Author: Andy Buckle
-Maintainer: Andy Buckle, John Donoghue
+Maintainer: John Donoghue
Title: dicom: file io for medical images and other data
Description: Digital communications in medicine (DICOM) file io.
Depends on Grassroots DICOM (GDCM). This package is not available
diff --git a/INDEX b/INDEX
index f4a3a2b..7c4198b 100644
--- a/INDEX
+++ b/INDEX
@@ -3,9 +3,11 @@ Dicom Functions
dicomanon
dicomdict
dicomdisp
+ dicomfind
dicominfo
dicomlookup
dicomread
dicomuid
+ dicomupdate
dicomwrite
isdicom
diff --git a/NEWS b/NEWS
index 9f47ba1..963ae0c 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,12 @@
+ Summary of important user-visible changes for dicom 0.5.0 (2022/06/30):
+-------------------------------------------------------------------------
+
+ ** added dicomfind and dicomupdate function
+
+ ** minor doc updates
+
+ ** added sample data files for example usage
+
Summary of important user-visible changes for dicom 0.4.1 (2022/02/22):
-------------------------------------------------------------------------
diff --git a/doc/dicom.pdf b/doc/dicom.pdf
index 44ec881..7fe8ba3 100644
--- a/doc/dicom.pdf
+++ b/doc/dicom.pdf
Binary files differ
diff --git a/doc/dicom.texi b/doc/dicom.texi
index 56660fa..7933575 100644
--- a/doc/dicom.texi
+++ b/doc/dicom.texi
@@ -136,7 +136,7 @@ read and write dicom data.
@example
%% read the meta information from a dicom file
-> info = dicominfo ('test.dcm');
+> info = dicominfo (file_in_loadpath('imdata/simple-test.dcm');
info =
scalar structure containing the fields:
Filename = a.dcm
@@ -176,8 +176,7 @@ info =
%% read the image data
-> image = dicomread('test.dcm')
-image = dicomread ('a.dcm')
+> image = dicomread(file_in_loadpath('imdata/simple-test.dcm'))
image =
0 0 0 0 0
0 0 0 0 0
diff --git a/doc/functions.texi b/doc/functions.texi
index 3eccd21..5800cf3 100644
--- a/doc/functions.texi
+++ b/doc/functions.texi
@@ -11,6 +11,7 @@
Anonymize a DICOM format file by removing or replacing specific fields.
+@subsubheading Inputs
@var{file_in} is filename to read from.@*
@var{file_out} is the filename to write to.@*
@var{name}, @var{value} optional name/value properties.@*
@@ -22,6 +23,8 @@ The value is a cell array of names to not remove during the anonymize procedure.
@item update
A structure of name/values to update rather than remove.
@end table
+@subsubheading Outputs
+None
@xseealso{dicomread, dicomwrite, dicominfo}
@end deftypefn
@@ -40,6 +43,27 @@ The first usage returns the filename of the dictionary that is currently being u
Using @code{factory} resets the dictionary to the default.
Using @code{set} allows setting the dictionary for future operations.
In this case, the dictionary file @var{dictionary_name} can be anywhere in the path.
+@subsubheading Inputs
+@var{code} - string value of 'get', 'set' or 'factory'.
+
+@var{dictionary_name'} - name of dictionary file to use
+
+@subsubheading Outputs
+@var{dictionary_name'} - name of dictionary file currently set for dictionaty
+
+@subsubheading Examples
+Get current dicom dict path:
+
+@example
+> f = dicomdict('get')
+f = octavedicom.dic
+@end example
+
+Set a new dictionary:
+
+@example
+> dicomdict('set', 'anewdictfile.txt')
+@end example
@xseealso{dicomread, dicomwrite}
@end deftypefn
@@ -52,13 +76,43 @@ In this case, the dictionary file @var{dictionary_name} can be anywhere in the p
@deftypefnx {Loadable Function} {} dicomdisp (@var{filename}, [@var{propertyname}, @var{propertvalue} ...])
Read and display the metadata from a DICOM file.
+@subsubheading Inputs
@var{filename} - dicomfilename to display.@*
@var{propertyname}, @var{propertvalue} - property pairs for options to the display function.
Currently the only known property is 'dictionary' to specify a non default dict to use.
+@subsubheading Outputs
+None
+
@xseealso{dicomread, dicominfo}
@end deftypefn
+@c Dicom Functions dicomfind
+@c -----------------------------------------
+@subsection dicomfind
+@cindex dicomfind
+ @deftypefn {} {@var{attrinfo}} = dicomfind(@var{filename}, @var{attribute})
+ @deftypefnx {} {@var{attrinfo}} = dicomfind(@var{info}, @var{attribute})
+ Find the location and value of an attribute in a dicom file or info structure.
+
+ @subsubheading Inputs
+ @var{filename} - filename to open.
+
+ @var{info} - dicominfo struct.
+
+ @var{attribute} - attribute name to find.
+
+ @subsubheading Outputs
+ @var{attrinfo} - a table with fields Location and Value fior each matched attribute.
+
+ @subsubheading Examples
+ @example
+ filename = file_in_loadpath("imdata/rtstruct.dcm");
+
+ info = dicomfind(filename, "ROINumber");
+
+ @end example
+ @end deftypefn
@c Dicom Functions dicominfo
@c -----------------------------------------
@subsection dicominfo
@@ -77,10 +131,62 @@ a DICOM dump.
If the @code{dictionary} argument is used, the given @var{dictionary-name} is used for this operation,
otherwise, the dictionary set by @code{dicomdict} is used.
+@subsubheading Inputs
+@var{filename} - name of file to read.
+
+@var{'dictionary'} - string constant of 'dictionary'.
+
+@var{dictionary-name} - filename of dictionary to use.
+
@var{options}:
@code{truncate=n}
where n is the number of characters to limit the dump output display to @code{n}
for each value.
+@subsubheading Outputs
+@var{info} - struct of fields read frome the dicom file.
+
+@subsubheading Examples
+Read the metadata of a dicomfile:
+
+@example
+> info = dicominfo(file_in_loadpath('imdata/simple-test.dcm')
+info =
+scalar structure containing the fields:
+Filename = a.dcm
+FileModDate = 04-Feb-2017 02:08:31
+FileMetaInformationVersion =
+0 1
+MediaStorageSOPClassUID = 1.2.840.10008.5.1.4.1.1.7
+MediaStorageSOPInstanceUID = 1.2.826.0.1.3680043.2.1143.4379544382488839209812957878553810312
+TransferSyntaxUID = 1.2.840.10008.1.2
+ImplementationClassUID = 1.2.826.0.1.3680043.2.1143.107.104.103.115.2.6.3
+ImplementationVersionName = GDCM 2.6.3
+SourceApplicationEntityTitle = GDCM
+ImageType = DERIVED \\SECONDARY
+SOPClassUID = 1.2.840.10008.5.1.4.1.1.7
+SOPInstanceUID = 1.2.826.0.1.3680043.2.1143.4379544382488839209812957878553810312
+StudyDate = 20170203
+StudyTime = 210831.360586
+Modality = OT
+ConversionType = WSD
+NominalScannedPixelSpacing =
+1
+1
+StudyInstanceUID = 1.2.826.0.1.3680043.2.1143.1282184104726305239898701219563360204
+SeriesInstanceUID = 1.2.826.0.1.3680043.2.1143.9385265081744858155080799316976198629
+SamplesPerPixel = 1
+PhotometricInterpretation = MONOCHROME1
+Rows = 10
+Columns = 5
+BitsAllocated = 8
+BitsStored = 8
+HighBit = 7
+PixelRepresentation = 0
+RescaleIntercept = 0
+RescaleSlope = 1
+RescaleType = US
+PixelData = not assigned
+@end example
@xseealso{dicomread, dicomdict}
@end deftypefn
@@ -102,6 +208,31 @@ of the attribute.
dictionary for a specified @var{keyword} string and returns the @var{group} and @var{element}
for keyword.
+@subsubheading Inputs
+@var{keyword} - string keyword name to look up a group, element value.@*
+@var{group} - group value to look up (string or integer).@*
+@var{element} - element value to look up (string or integer).@*
+
+@subsubheading Outputs
+@var{keyword} - string keyword name to looked up from a group, element value.@*
+@var{group}, @var{element} - group and element value looked up from keyword.@*
+
+@subsubheading Outputs
+Look up tag name for 0x10 0x10:
+
+@example
+> name = dicomlookup(0x10,0x10)
+name = PatientName
+
+@end example
+
+Look up tag group and element value:
+
+@example
+> [grp, elm] = dicomlookup('TransferSyntaxUID')
+grp = 2
+elm = 16
+@end example
@xseealso{dicomdict}
@end deftypefn
@@ -113,10 +244,33 @@ for keyword.
@deftypefnx {Loadable Function} @var{image} = dicomread (@var{structure})
Load the image from a DICOM file.
-@var{filename} is a string (giving the filename).
-@var{structure} is a structure with a field @code{Filename} (such as returned by @code{dicominfo}).
-@var{image} may be two or three dimensional, depending on the content of the file.
-An integer or float matrix will be returned, the number of bits will depend on the file.
+@subsubheading Inputs
+@var{filename} - a string giving the filename.*
+
+@var{structure} - a structure with a field @code{Filename} (such as returned by @code{dicominfo}).
+
+@var{image} - may be two or three dimensional, depending on the content of the file.
+
+@subsubheading Outputs
+@var{image} - An integer or float matrix will be returned, the number of bits will depend on the file.
+
+@subsubheading Examples
+Load the image data of a dcm file:
+
+@example
+> image = dicomread(file_in_load_path('imdata/simple-test.dcm'))
+image =
+0 0 0 0 0
+0 0 0 0 0
+0 0 0 0 0
+0 0 0 0 0
+0 0 0 0 0
+0 0 0 0 0
+0 0 0 0 0
+0 0 0 0 0
+0 0 0 0 0
+0 0 0 0 0
+@end example
@xseealso{dicominfo}
@end deftypefn
@@ -129,10 +283,56 @@ An integer or float matrix will be returned, the number of bits will depend on t
Generate a DICOM unique id .
+@subsubheading Inputs
+None
+@subsubheading Outputs
@var{uuid} is a unique id string.
+@subsubheading Examples
+Get a new uid:
+
+@example
+> uid = dicomuid ()
+uid = 1.2.826.0.1.3680043.2.1143.3114589836670200378351641061429967573
+@end example
+
@end deftypefn
+@c Dicom Functions dicomupdate
+@c -----------------------------------------
+@subsection dicomupdate
+@cindex dicomupdate
+ @deftypefn {} {@var{info} =} dicomupdate(@var{fileinfo}, @var{attribute}, @var{value})
+ @deftypefnx {} {@var{info} =} dicomupdate(@var{info}, @var{attrinfo})
+ Update a dicom struct with new values
+
+ @subsubheading Inputs
+ @var{info} - dicominfo struct.
+
+ @var{attribute} - attribute name to find and change value of.
+
+ @var{value} - attribute value to set.
+
+ @var{attrinfo} - a table with fields Location and Value for each matched attribute to change.
+
+ @subsubheading Outputs
+ @var{info} - dicominfo struct.
+
+ @subsubheading Examples
+ @example
+ filename = file_in_loadpath("imdata/rtstruct.dcm");
+ info = dicominfo(filename);
+
+ % update specific values
+ finfo = dicomfind(info, "ROINumber");
+ finfo.Value@{1@} = 10;
+ info = dicomupdate(info, finfo);
+
+ % update all matching
+ info = dicomupdate(info, "ROINumber", 100);
+
+ @end example
+ @end deftypefn
@c Dicom Functions dicomwrite
@c -----------------------------------------
@subsection dicomwrite
@@ -142,9 +342,27 @@ Generate a DICOM unique id .
Write a DICOM format file to @var{filename}.
-@var{im} is image data or empty matrix, [], if only metadata save is required
-@var{filename} is filename to write dicom to. if [], then function runs in verbose trial mode.
-@var{info} struct, like that produced by dicominfo
+@subsubheading Inputs
+@var{im} - image data or empty matrix, [], if only metadata save is required
+
+@var{filename} - filename to write dicom to. if [], then function runs in verbose trial mode.
+
+@var{info} - struct, like that produced by dicominfo
+
+@subsubheading Examples
+Create a dicom file using default info, and the supplied data:
+@example
+> wdata = uint8 (10*rand (10,10));
+> dicomwrite (wdata, 'test.dcm');
+@end example
+
+Create a dicom file using data and meta info:
+
+@example
+> wdata = dicomread(file_in_loadpath('imdata/CT-MONO2-16-ankle.dcm');
+> info = dicominfo(file_in_loadpath('imdata/CT-MONO2-16-ankle.dcm');
+> dicomwrite(wdata, info);
+@end example
@xseealso{dicomread, dicominfo}
@end deftypefn
@@ -153,8 +371,14 @@ Write a DICOM format file to @var{filename}.
@c -----------------------------------------
@subsection isdicom
@cindex isdicom
-@deftypefn {Loadable Function} {} isdicom (@var{filename})
+@deftypefn {Loadable Function} {@var{yesno} =} isdicom (@var{filename})
Return true if @var{filename} is a valid DICOM file.
+@subsubheading Inputs
+@var{filename} - name of file to read.
+
+@subsubheading Outputs
+@var{yesno} - logical value of true if filename is a dicom file.
+
@xseealso{dicomdict, dicominfo, dicomread, dicomwrite}
@end deftypefn
diff --git a/inst/dicomfind.m b/inst/dicomfind.m
new file mode 100644
index 0000000..c8fcccf
--- /dev/null
+++ b/inst/dicomfind.m
@@ -0,0 +1,111 @@
+## Copyright (C) 2022 John Donoghue <john.donoghue@ieee.org>
+##
+## 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/>.
+
+## -*- texinfo -*-
+## @deftypefn {} {@var{attrinfo}} = dicomfind(@var{filename}, @var{attribute})
+## @deftypefnx {} {@var{attrinfo}} = dicomfind(@var{info}, @var{attribute})
+## Find the location and value of an attribute in a dicom file or info structure.
+##
+## @subsubheading Inputs
+## @var{filename} - filename to open.
+##
+## @var{info} - dicominfo struct.
+##
+## @var{attribute} - attribute name to find.
+##
+## @subsubheading Outputs
+## @var{attrinfo} - a table with fields Location and Value fior each matched attribute.
+##
+## @subsubheading Examples
+## @example
+## filename = file_in_loadpath("imdata/rtstruct.dcm");
+##
+## info = dicomfind(filename, "ROINumber");
+##
+## @end example
+## @end deftypefn
+
+function data = dicomfind(filename, attributename)
+ if ischar(filename)
+ info = dicominfo(filename);
+ elseif isstruct(filename)
+ info = filename;
+ else
+ error ("Expected first argument as a filename or dicominfo structure");
+ endif
+
+ if !ischar(attributename)
+ error ("Expected attribute as a string");
+ endif
+
+ data = recurse_dicom_struct(info, "", attributename);
+endfunction
+
+function data = recurse_dicom_struct(info, base, name)
+ data = struct('Location', [], 'Value', []);
+
+ names = fieldnames(info);
+ for idx = 1:length(names)
+ fieldname = names{idx};
+ fieldval = info.(fieldname);
+ fieldtype = class(fieldval);
+ if length(base) == 0
+ nbase = fieldname;
+ else
+ nbase = [base "." fieldname];
+ endif
+
+ if strcmp(fieldtype, "struct")
+ ndata = recurse_dicom_struct(fieldval, nbase, name);
+ if !isempty(ndata) && !isempty(ndata.Location)
+ #ndata
+ if isempty(data.Location)
+ data.Location = [ ndata.Location ];
+ data.Value = [ ndata.Value ];
+ else
+ data.Location = [ data.Location; ndata.Location ];
+ data.Value = [ data.Value; ndata.Value ];
+ endif
+ endif
+ else
+ if strcmp(fieldname, name)
+ if isempty(data.Location)
+ data.Location = [{nbase}];
+ data.Value = [{fieldval}];
+ else
+ data.Location = [ data.Location; {nbase} ];
+ data.Value = [ data.Value; {fieldval} ];
+ endif
+ endif
+ endif
+ endfor
+
+endfunction
+
+%!test
+%! filename = file_in_loadpath("imdata/rtstruct.dcm");
+%! info = dicomfind(filename, "ROINumber");
+%! assert(length(info.Location),4)
+%! assert(length(info.Value),4)
+%! assert(info.Location{1}, 'StructureSetROISequence.Item_1.ROINumber')
+
+%!test
+%! filename = file_in_loadpath("imdata/rtstruct.dcm");
+%! dinfo = dicominfo(filename);
+%! info = dicomfind(dinfo, "ROINumber");
+%! assert(length(info.Location),4)
+%! assert(length(info.Value),4)
+%! assert(info.Location{1}, 'StructureSetROISequence.Item_1.ROINumber')
+
diff --git a/inst/dicomupdate.m b/inst/dicomupdate.m
new file mode 100644
index 0000000..edec7e1
--- /dev/null
+++ b/inst/dicomupdate.m
@@ -0,0 +1,141 @@
+## Copyright (C) 2022 John Donoghue <john.donoghue@ieee.org>
+##
+## 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/>.
+
+## -*- texinfo -*-
+## @deftypefn {} {@var{info} =} dicomupdate(@var{fileinfo}, @var{attribute}, @var{value})
+## @deftypefnx {} {@var{info} =} dicomupdate(@var{info}, @var{attrinfo})
+## Update a dicom struct with new values
+##
+## @subsubheading Inputs
+## @var{info} - dicominfo struct.
+##
+## @var{attribute} - attribute name to find and change value of.
+##
+## @var{value} - attribute value to set.
+##
+## @var{attrinfo} - a table with fields Location and Value for each matched attribute to change.
+##
+## @subsubheading Outputs
+## @var{info} - dicominfo struct.
+##
+## @subsubheading Examples
+## @example
+## filename = file_in_loadpath("imdata/rtstruct.dcm");
+## info = dicominfo(filename);
+##
+## % update specific values
+## finfo = dicomfind(info, "ROINumber");
+## finfo.Value@{1@} = 10;
+## info = dicomupdate(info, finfo);
+##
+## % update all matching
+## info = dicomupdate(info, "ROINumber", 100);
+##
+## @end example
+## @end deftypefn
+
+function info = dicomupdate(info, attrname, value=0)
+
+ # if attrname is a char, need find positions
+ if ischar(attrname)
+ if nargin != 3
+ error ("Expected value");
+ endif
+ attribinfo = dicomfind(info, attrname);
+ else
+ attribinfo = attrname;
+ if nargin != 2
+ error ("Unexpected value");
+ endif
+ if !isfield(attribinfo, "Location") || !isfield(attribinfo, "Value")
+ error ("Expected struct to contain Location and Value fields");
+ endif
+ endif
+ for idx=1:size(attribinfo.Location, 1)
+ if size(attribinfo.Location, 1) == 1
+ loc = attribinfo.Location;
+ if nargin > 2
+ val = value;
+ else
+ val = attribinfo.Value
+ endif
+ else
+ loc = attribinfo.Location{idx};
+ if nargin > 2
+ val = value;
+ else
+ val = attribinfo.Value{idx};
+ endif
+ endif
+ # set value in location
+ info = recurse_set_dicom_struct(info, "", loc, val);
+ endfor
+
+endfunction
+
+function info = recurse_set_dicom_struct(info, base, name, value)
+
+ names = fieldnames(info);
+
+ # TODO: rather than recurse till find, we could traverse down the struct
+ for idx = 1:length(names)
+ fieldname = names{idx};
+ fieldval = info.(fieldname);
+ fieldtype = class(fieldval);
+ if length(base) == 0
+ nbase = fieldname;
+ else
+ nbase = [base "." fieldname];
+ endif
+
+ if strcmp(fieldtype, "struct")
+ info.(fieldname) = recurse_set_dicom_struct(fieldval, nbase, name, value);
+ else
+ if strcmp(nbase, name)
+ info.(fieldname) = value;
+ endif
+ endif
+ endfor
+
+endfunction
+
+%!test
+%! filename = file_in_loadpath("imdata/rtstruct.dcm");
+%! info = dicominfo(filename);
+%! finfo = dicomfind(info, "ROINumber");
+%! assert(length(finfo.Location),4);
+%! assert(length(finfo.Value),4);
+%! assert(finfo.Location{1}, 'StructureSetROISequence.Item_1.ROINumber');
+%! assert(finfo.Value{1}, 2);
+%! finfo.Value{1} = 10;
+%! info = dicomupdate(info, finfo);
+%! finfo = dicomfind(info, "ROINumber");
+%! assert(finfo.Value{1}, 10);
+
+%!test
+%! filename = file_in_loadpath("imdata/rtstruct.dcm");
+%! info = dicominfo(filename);
+%! finfo = dicomfind(info, "ROINumber");
+%! assert(length(finfo.Location),4);
+%! assert(length(finfo.Value),4);
+%! assert(finfo.Location{1}, 'StructureSetROISequence.Item_1.ROINumber');
+%! assert(finfo.Value{1}, 2);
+%! info = dicomupdate(info, "ROINumber", 100);
+%! finfo = dicomfind(info, "ROINumber");
+%! assert(finfo.Value{1}, 100);
+%! assert(finfo.Value{2}, 100);
+%! assert(finfo.Value{3}, 100);
+%! assert(finfo.Value{4}, 100);
+
diff --git a/inst/imdata/CT-MONO2-16-ankle.dcm b/inst/imdata/CT-MONO2-16-ankle.dcm
new file mode 100644
index 0000000..ecfe6ce
--- /dev/null
+++ b/inst/imdata/CT-MONO2-16-ankle.dcm
Binary files differ
diff --git a/inst/imdata/README.md b/inst/imdata/README.md
new file mode 100644
index 0000000..3d207cc
--- /dev/null
+++ b/inst/imdata/README.md
@@ -0,0 +1,2 @@
+test data taken from the gdcmData repo of GDCM.
+http://sourceforge.net/projects/gdcm/files/gdcmData/gdcmData/
diff --git a/inst/imdata/US-PAL-8-10x-echo.dcm b/inst/imdata/US-PAL-8-10x-echo.dcm
new file mode 100644
index 0000000..771447f
--- /dev/null
+++ b/inst/imdata/US-PAL-8-10x-echo.dcm
Binary files differ
diff --git a/inst/imdata/rtstruct.dcm b/inst/imdata/rtstruct.dcm
new file mode 100644
index 0000000..b144842
--- /dev/null
+++ b/inst/imdata/rtstruct.dcm
Binary files differ
diff --git a/inst/imdata/simple-test.dcm b/inst/imdata/simple-test.dcm
new file mode 100644
index 0000000..cadebeb
--- /dev/null
+++ b/inst/imdata/simple-test.dcm
Binary files differ
diff --git a/inst/imdata/simpleImageWithIcon.dcm b/inst/imdata/simpleImageWithIcon.dcm
new file mode 100644
index 0000000..e9d2d66
--- /dev/null
+++ b/inst/imdata/simpleImageWithIcon.dcm
Binary files differ
diff --git a/src/config.h.in b/src/config.h.in
index 57d0f41..a9b103c 100644
--- a/src/config.h.in
+++ b/src/config.h.in
@@ -2,6 +2,9 @@
#include "undef-ah-octave.h"
+/* Define to 1 if you have the <gdcmVersion.h> header file. */
+#undef HAVE_GDCMVERSION_H
+
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
diff --git a/src/configure b/src/configure
index ef866df..62a28e0 100755
--- a/src/configure
+++ b/src/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for Octave-Forge dicom package 0.4.1.
+# Generated by GNU Autoconf 2.69 for Octave-Forge dicom package 0.5.0.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -577,8 +577,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='Octave-Forge dicom package'
PACKAGE_TARNAME='octave-forge-dicom-package'
-PACKAGE_VERSION='0.4.1'
-PACKAGE_STRING='Octave-Forge dicom package 0.4.1'
+PACKAGE_VERSION='0.5.0'
+PACKAGE_STRING='Octave-Forge dicom package 0.5.0'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
@@ -620,11 +620,11 @@ ac_includes_default="\
ac_subst_vars='LTLIBOBJS
LIBOBJS
-EGREP
-CXXCPP
GDCM_LIBS
GDCM_CXXFLAGS
CMAKE_BINARY
+EGREP
+CXXCPP
OBJEXT
EXEEXT
ac_ct_CXX
@@ -702,10 +702,10 @@ LDFLAGS
LIBS
CPPFLAGS
CCC
+CXXCPP
CMAKE_BINARY
GDCM_CXXFLAGS
-GDCM_LIBS
-CXXCPP'
+GDCM_LIBS'
# Initialize some variables set by options.
@@ -1256,7 +1256,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures Octave-Forge dicom package 0.4.1 to adapt to many kinds of systems.
+\`configure' configures Octave-Forge dicom package 0.5.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1324,7 +1324,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of Octave-Forge dicom package 0.4.1:";;
+ short | recursive ) echo "Configuration of Octave-Forge dicom package 0.5.0:";;
esac
cat <<\_ACEOF
@@ -1336,12 +1336,12 @@ Some influential environment variables:
LIBS libraries to pass to the linker, e.g. -l<library>
CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
you have headers in a nonstandard directory <include dir>
+ CXXCPP C++ preprocessor
CMAKE_BINARY
path to the cmake binary
GDCM_CXXFLAGS
CXX compiler flags for GDCM. This overrides the cmake output
GDCM_LIBS linker flags for GDCM. This overrides the cmake output
- CXXCPP C++ preprocessor
Use these variables to override the choices made by `configure' or to help
it to find libraries and programs with nonstandard names/locations.
@@ -1409,7 +1409,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-Octave-Forge dicom package configure 0.4.1
+Octave-Forge dicom package configure 0.5.0
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1461,52 +1461,6 @@ fi
} # ac_fn_cxx_try_compile
-# ac_fn_cxx_try_link LINENO
-# -------------------------
-# Try to link conftest.$ac_ext, and return whether this succeeded.
-ac_fn_cxx_try_link ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- rm -f conftest.$ac_objext conftest$ac_exeext
- if { { ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_link") 2>conftest.err
- ac_status=$?
- if test -s conftest.err; then
- grep -v '^ *+' conftest.err >conftest.er1
- cat conftest.er1 >&5
- mv -f conftest.er1 conftest.err
- fi
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } && {
- test -z "$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext && {
- test "$cross_compiling" = yes ||
- test -x conftest$ac_exeext
- }; then :
- ac_retval=0
-else
- $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_retval=1
-fi
- # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
- # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
- # interfere with the next link command; also delete a directory that is
- # left behind by Apple's compiler. We do this before executing the actions.
- rm -rf conftest.dSYM conftest_ipa8_conftest.oo
- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
- as_fn_set_status $ac_retval
-
-} # ac_fn_cxx_try_link
-
# ac_fn_cxx_try_cpp LINENO
# ------------------------
# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
@@ -1703,11 +1657,57 @@ $as_echo "$ac_res" >&6; }
eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
} # ac_fn_cxx_check_header_compile
+
+# ac_fn_cxx_try_link LINENO
+# -------------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_try_link ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ test -x conftest$ac_exeext
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+ # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+ # interfere with the next link command; also delete a directory that is
+ # left behind by Apple's compiler. We do this before executing the actions.
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_link
cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by Octave-Forge dicom package $as_me 0.4.1, which was
+It was created by Octave-Forge dicom package $as_me 0.5.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -3004,6 +3004,351 @@ ac_cpp='$CXXCPP $CPPFLAGS'
ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5
+$as_echo_n "checking how to run the C++ preprocessor... " >&6; }
+if test -z "$CXXCPP"; then
+ if ${ac_cv_prog_CXXCPP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # Double quotes because CXXCPP needs to be expanded
+ for CXXCPP in "$CXX -E" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+ break
+fi
+
+ done
+ ac_cv_prog_CXXCPP=$CXXCPP
+
+fi
+ CXXCPP=$ac_cv_prog_CXXCPP
+else
+ ac_cv_prog_CXXCPP=$CXXCPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5
+$as_echo "$CXXCPP" >&6; }
+ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+# check can access std c files
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if ${ac_cv_path_EGREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+ then ac_cv_path_EGREP="$GREP -E"
+ else
+ if test -z "$EGREP"; then
+ ac_path_EGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in egrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_EGREP" || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+ # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'EGREP' >> "conftest.nl"
+ "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_EGREP="$ac_path_EGREP"
+ ac_path_EGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_EGREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_EGREP"; then
+ as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_EGREP=$EGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_header_stdc=yes
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then :
+ :
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ return 2;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_run "$LINENO"; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+ inttypes.h stdint.h unistd.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_cxx_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+for ac_header in string.h
+do :
+ ac_fn_cxx_check_header_mongrel "$LINENO" "string.h" "ac_cv_header_string_h" "$ac_includes_default"
+if test "x$ac_cv_header_string_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_STRING_H 1
+_ACEOF
+
+fi
+
+done
## octave API tests
@@ -3021,7 +3366,6 @@ LIBS="-loctinterp $LIBS"
# need to use interpreter->get_load_path in dev version of octave,
# prior to that methods of load_path were static
-
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking interpreter get_load_path" >&5
$as_echo_n "checking interpreter get_load_path... " >&6; }
if ${octave_cv_interpreter_get_load_path+:} false; then :
@@ -3341,10 +3685,34 @@ else
$as_echo "yes" >&6; }
fi
+if test "$GDCM_CXXFLAGS$GDCM_LIBS" != "" ; then
+ # if have cmake detection, see if can find include files
+
+ save_CPPFLAGS=$CPPFLAGS
+ CPPFLAGS="$CPPFLAGS $GDCM_CXXFLAGS"
+
+ for ac_header in gdcmVersion.h
+do :
+ ac_fn_cxx_check_header_mongrel "$LINENO" "gdcmVersion.h" "ac_cv_header_gdcmVersion_h" "$ac_includes_default"
+if test "x$ac_cv_header_gdcmVersion_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_GDCMVERSION_H 1
+_ACEOF
+
+else
+ GDCM_CXXFLAGS=""; GDCM_LIBS=""
+fi
+
+done
+
+
+ CPPFLAGS=$save_CPPFLAGS
+fi
+
# newer cmake seems to have issues so if found nothing, and dont have anything set, then try hard way
if test "$GDCM_CXXFLAGS$GDCM_LIBS" == "" ; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: No GDCM detected using cmake - trying fallback detection" >&5
-$as_echo "$as_me: WARNING: No GDCM detected using cmake - trying fallback detection" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Trying fallback GDCM detection" >&5
+$as_echo "$as_me: Trying fallback GDCM detection" >&6;}
#AC_LANG(C++)
save_LDFLAGS=$LDFLAGS
@@ -3417,7 +3785,7 @@ fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
- LDFLAGS=$saved_LDFLAGS
+ LDFLAGS=$save_LDFLAGS
CPPFLAGS=$save_CPPFLAGS
fi
@@ -3442,336 +3810,6 @@ CPPFLAGS="$CPPFLAGS $GDCM_CXXFLAGS"
## All the GDCM headers we use (we should probably have something less ugly)
GDCM_HEADERS=$($SED -n 's,^#include.*"\(gdcm[^"]*\)\".*$,\1,p' *.cpp *.h | $SORT | $UNIQ)
-ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5
-$as_echo_n "checking how to run the C++ preprocessor... " >&6; }
-if test -z "$CXXCPP"; then
- if ${ac_cv_prog_CXXCPP+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- # Double quotes because CXXCPP needs to be expanded
- for CXXCPP in "$CXX -E" "/lib/cpp"
- do
- ac_preproc_ok=false
-for ac_cxx_preproc_warn_flag in '' yes
-do
- # Use a header file that comes with gcc, so configuring glibc
- # with a fresh cross-compiler works.
- # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- # <limits.h> exists even on freestanding compilers.
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp. "Syntax error" is here to catch this case.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
- Syntax error
-_ACEOF
-if ac_fn_cxx_try_cpp "$LINENO"; then :
-
-else
- # Broken: fails on valid input.
-continue
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-
- # OK, works on sane cases. Now check whether nonexistent headers
- # can be detected and how.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <ac_nonexistent.h>
-_ACEOF
-if ac_fn_cxx_try_cpp "$LINENO"; then :
- # Broken: success on invalid input.
-continue
-else
- # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.i conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then :
- break
-fi
-
- done
- ac_cv_prog_CXXCPP=$CXXCPP
-
-fi
- CXXCPP=$ac_cv_prog_CXXCPP
-else
- ac_cv_prog_CXXCPP=$CXXCPP
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5
-$as_echo "$CXXCPP" >&6; }
-ac_preproc_ok=false
-for ac_cxx_preproc_warn_flag in '' yes
-do
- # Use a header file that comes with gcc, so configuring glibc
- # with a fresh cross-compiler works.
- # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- # <limits.h> exists even on freestanding compilers.
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp. "Syntax error" is here to catch this case.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
- Syntax error
-_ACEOF
-if ac_fn_cxx_try_cpp "$LINENO"; then :
-
-else
- # Broken: fails on valid input.
-continue
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-
- # OK, works on sane cases. Now check whether nonexistent headers
- # can be detected and how.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <ac_nonexistent.h>
-_ACEOF
-if ac_fn_cxx_try_cpp "$LINENO"; then :
- # Broken: success on invalid input.
-continue
-else
- # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.i conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then :
-
-else
- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check
-See \`config.log' for more details" "$LINENO" 5; }
-fi
-
-ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
-$as_echo_n "checking for egrep... " >&6; }
-if ${ac_cv_path_EGREP+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
- then ac_cv_path_EGREP="$GREP -E"
- else
- if test -z "$EGREP"; then
- ac_path_EGREP_found=false
- # Loop through the user's path and test for each of PROGNAME-LIST
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_prog in egrep; do
- for ac_exec_ext in '' $ac_executable_extensions; do
- ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
- as_fn_executable_p "$ac_path_EGREP" || continue
-# Check for GNU ac_path_EGREP and select it if it is found.
- # Check for GNU $ac_path_EGREP
-case `"$ac_path_EGREP" --version 2>&1` in
-*GNU*)
- ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
-*)
- ac_count=0
- $as_echo_n 0123456789 >"conftest.in"
- while :
- do
- cat "conftest.in" "conftest.in" >"conftest.tmp"
- mv "conftest.tmp" "conftest.in"
- cp "conftest.in" "conftest.nl"
- $as_echo 'EGREP' >> "conftest.nl"
- "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
- diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
- as_fn_arith $ac_count + 1 && ac_count=$as_val
- if test $ac_count -gt ${ac_path_EGREP_max-0}; then
- # Best one so far, save it but keep looking for a better one
- ac_cv_path_EGREP="$ac_path_EGREP"
- ac_path_EGREP_max=$ac_count
- fi
- # 10*(2^10) chars as input seems more than enough
- test $ac_count -gt 10 && break
- done
- rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
-esac
-
- $ac_path_EGREP_found && break 3
- done
- done
- done
-IFS=$as_save_IFS
- if test -z "$ac_cv_path_EGREP"; then
- as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
- fi
-else
- ac_cv_path_EGREP=$EGREP
-fi
-
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
-$as_echo "$ac_cv_path_EGREP" >&6; }
- EGREP="$ac_cv_path_EGREP"
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
-$as_echo_n "checking for ANSI C header files... " >&6; }
-if ${ac_cv_header_stdc+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <float.h>
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
- ac_cv_header_stdc=yes
-else
- ac_cv_header_stdc=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
-if test $ac_cv_header_stdc = yes; then
- # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <string.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "memchr" >/dev/null 2>&1; then :
-
-else
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
- # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <stdlib.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "free" >/dev/null 2>&1; then :
-
-else
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
- # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
- if test "$cross_compiling" = yes; then :
- :
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <ctype.h>
-#include <stdlib.h>
-#if ((' ' & 0x0FF) == 0x020)
-# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
-# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
-#else
-# define ISLOWER(c) \
- (('a' <= (c) && (c) <= 'i') \
- || ('j' <= (c) && (c) <= 'r') \
- || ('s' <= (c) && (c) <= 'z'))
-# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
-#endif
-
-#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
-int
-main ()
-{
- int i;
- for (i = 0; i < 256; i++)
- if (XOR (islower (i), ISLOWER (i))
- || toupper (i) != TOUPPER (i))
- return 2;
- return 0;
-}
-_ACEOF
-if ac_fn_cxx_try_run "$LINENO"; then :
-
-else
- ac_cv_header_stdc=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
- conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
-
-fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
-$as_echo "$ac_cv_header_stdc" >&6; }
-if test $ac_cv_header_stdc = yes; then
-
-$as_echo "#define STDC_HEADERS 1" >>confdefs.h
-
-fi
-
-# On IRIX 5.3, sys/types and inttypes.h are conflicting.
-for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
- inttypes.h stdint.h unistd.h
-do :
- as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
-ac_fn_cxx_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
-"
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
- cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
-done
-
-
for ac_header in $GDCM_HEADERS
do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
@@ -4299,7 +4337,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by Octave-Forge dicom package $as_me 0.4.1, which was
+This file was extended by Octave-Forge dicom package $as_me 0.5.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -4361,7 +4399,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-Octave-Forge dicom package config.status 0.4.1
+Octave-Forge dicom package config.status 0.5.0
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/src/configure.ac b/src/configure.ac
index 371a1ac..05dc53b 100644
--- a/src/configure.ac
+++ b/src/configure.ac
@@ -18,7 +18,7 @@
### <http://www.gnu.org/licenses/>.
AC_PREREQ([2.67])
-AC_INIT([Octave-Forge dicom package], [0.4.1])
+AC_INIT([Octave-Forge dicom package], [0.5.0])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIRS([m4])
AH_TOP([#include "undef-ah-octave.h"])
@@ -40,8 +40,12 @@ AC_CHECK_PROG(OCTAVE_CONFIG,octave-config,octave-config)
test -z "$OCTAVE_CONFIG" && OCTAVE_CONFIG=$MKOCTFILE
AC_PROG_CXX
+AC_PROG_CXXCPP
AC_LANG(C++)
+# check can access std c files
+AC_CHECK_HEADERS([string.h])
+
## octave API tests
save_CXX="$CXX"
save_CXXFLAGS="$CXXFLAGS"
@@ -131,9 +135,22 @@ dnl dependent directories.
dnl
CMAKE_FIND_PACKAGE([GDCM], [CXX], , , , [target_arch])
+if test "$GDCM_CXXFLAGS$GDCM_LIBS" != "" ; then
+ # if have cmake detection, see if can find include files
+
+ save_CPPFLAGS=$CPPFLAGS
+ CPPFLAGS="$CPPFLAGS $GDCM_CXXFLAGS"
+
+ AC_CHECK_HEADERS([gdcmVersion.h], ,
+ [GDCM_CXXFLAGS=""; GDCM_LIBS=""],
+ )
+
+ CPPFLAGS=$save_CPPFLAGS
+fi
+
# newer cmake seems to have issues so if found nothing, and dont have anything set, then try hard way
if test "$GDCM_CXXFLAGS$GDCM_LIBS" == "" ; then
- AC_MSG_WARN([No GDCM detected using cmake - trying fallback detection])
+ AC_MSG_NOTICE([Trying fallback GDCM detection])
#AC_LANG(C++)
save_LDFLAGS=$LDFLAGS
@@ -177,7 +194,7 @@ if test "$GDCM_CXXFLAGS$GDCM_LIBS" == "" ; then
[AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])])
- LDFLAGS=$saved_LDFLAGS
+ LDFLAGS=$save_LDFLAGS
CPPFLAGS=$save_CPPFLAGS
fi
diff --git a/src/dicomanon.cpp b/src/dicomanon.cpp
index a948d96..1d5c918 100644
--- a/src/dicomanon.cpp
+++ b/src/dicomanon.cpp
@@ -56,6 +56,7 @@ DEFUN_DLD (dicomanon, args, nargout,
\n\
Anonymize a DICOM format file by removing or replacing specific fields.\n\
\n\
+@subsubheading Inputs\n\
@var{file_in} is filename to read from.@*\n\
@var{file_out} is the filename to write to.@*\n\
@var{name}, @var{value} optional name/value properties.@*\n\
@@ -67,6 +68,8 @@ The value is a cell array of names to not remove during the anonymize procedure.
@item update\n\
A structure of name/values to update rather than remove.\n\
@end table\n\
+@subsubheading Outputs\n\
+None\n\
\n\
@seealso{dicomread, dicomwrite, dicominfo}\n\
@end deftypefn \n\
diff --git a/src/dicomdict.cpp b/src/dicomdict.cpp
index 17dd0ad..f2bd28e 100644
--- a/src/dicomdict.cpp
+++ b/src/dicomdict.cpp
@@ -78,6 +78,27 @@ The first usage returns the filename of the dictionary that is currently being u
Using @code{factory} resets the dictionary to the default.\n\
Using @code{set} allows setting the dictionary for future operations.\n\
In this case, the dictionary file @var{dictionary_name} can be anywhere in the path.\n\
+@subsubheading Inputs\n\
+@var{code} - string value of 'get', 'set' or 'factory'.\n\
+\n\
+@var{dictionary_name'} - name of dictionary file to use\n \
+\n\
+@subsubheading Outputs\n\
+@var{dictionary_name'} - name of dictionary file currently set for dictionaty\n \
+\n\
+@subsubheading Examples\n\
+Get current dicom dict path:\n\
+\n\
+@example\n\
+> f = dicomdict('get')\n\
+f = octavedicom.dic\n\
+@end example\n\
+\n\
+Set a new dictionary:\n\
+\n\
+@example\n\
+> dicomdict('set', 'anewdictfile.txt')\n\
+@end example\n\
\n\
@seealso{dicomread, dicomwrite}\n\
@end deftypefn \n")
diff --git a/src/dicomdisp.cpp b/src/dicomdisp.cpp
index fca7260..9279dc8 100644
--- a/src/dicomdisp.cpp
+++ b/src/dicomdisp.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright John Donoghue, 2019:
+ * Copyright John Donoghue, 2019-2022:
*
* The GNU Octave dicom package is free software: you can redistribute
* it and/or modify it under the terms of the GNU General Public
@@ -68,10 +68,14 @@ DEFUN_DLD (dicomdisp, args, nargout,
@deftypefnx {Loadable Function} {} dicomdisp (@var{filename}, [@var{propertyname}, @var{propertvalue} ...]) \n\
Read and display the metadata from a DICOM file.\n\
\n\
+ @subsubheading Inputs\n\
@var{filename} - dicomfilename to display.@*\n \
@var{propertyname}, @var{propertvalue} - property pairs for options to the display function.\n \
\n \
Currently the only known property is 'dictionary' to specify a non default dict to use.\n \
+ @subsubheading Outputs\n\
+ None\n\
+ \n\
@seealso{dicomread, dicominfo} \n\
@end deftypefn\n\
")
diff --git a/src/dicominfo.cpp b/src/dicominfo.cpp
index 4940c66..4b190c6 100644
--- a/src/dicominfo.cpp
+++ b/src/dicominfo.cpp
@@ -1,5 +1,5 @@
/*
- * The GNU Octave dicom package is Copyright Andy Buckle 2010-2020
+ * The GNU Octave dicom package is Copyright Andy Buckle 2010-2022
* Contact: blondandy using the sf.net system,
* <https://sourceforge.net/sendmessage.php?touser=1760416>
*
@@ -103,10 +103,62 @@ a DICOM dump. \n\
If the @code{dictionary} argument is used, the given @var{dictionary-name} is used for this operation, \n\
otherwise, the dictionary set by @code{dicomdict} is used.\n\
\n\
+@subsubheading Inputs\n\
+@var{filename} - name of file to read.\n\
+\n\
+@var{'dictionary'} - string constant of 'dictionary'.\n\
+\n\
+@var{dictionary-name} - filename of dictionary to use.\n\
+\n\
@var{options}:\n\
@code{truncate=n}\n\
where n is the number of characters to limit the dump output display to @code{n}\
for each value. \n\
+@subsubheading Outputs\n\
+@var{info} - struct of fields read frome the dicom file.\n\
+\n\
+@subsubheading Examples\n\
+Read the metadata of a dicomfile:\n\
+\n\
+@example\n \
+> info = dicominfo(file_in_loadpath('imdata/simple-test.dcm')\n \
+info = \n \
+ scalar structure containing the fields:\n \
+ Filename = a.dcm\n \
+ FileModDate = 04-Feb-2017 02:08:31\n \
+ FileMetaInformationVersion =\n \
+ 0 1\n \
+ MediaStorageSOPClassUID = 1.2.840.10008.5.1.4.1.1.7\n \
+ MediaStorageSOPInstanceUID = 1.2.826.0.1.3680043.2.1143.4379544382488839209812957878553810312\n \
+ TransferSyntaxUID = 1.2.840.10008.1.2\n \
+ ImplementationClassUID = 1.2.826.0.1.3680043.2.1143.107.104.103.115.2.6.3\n \
+ ImplementationVersionName = GDCM 2.6.3\n \
+ SourceApplicationEntityTitle = GDCM\n \
+ ImageType = DERIVED \\SECONDARY \n \
+ SOPClassUID = 1.2.840.10008.5.1.4.1.1.7\n \
+ SOPInstanceUID = 1.2.826.0.1.3680043.2.1143.4379544382488839209812957878553810312\n \
+ StudyDate = 20170203\n \
+ StudyTime = 210831.360586 \n \
+ Modality = OT\n \
+ ConversionType = WSD \n \
+ NominalScannedPixelSpacing =\n \
+ 1\n \
+ 1\n \
+ StudyInstanceUID = 1.2.826.0.1.3680043.2.1143.1282184104726305239898701219563360204\n \
+ SeriesInstanceUID = 1.2.826.0.1.3680043.2.1143.9385265081744858155080799316976198629\n \
+ SamplesPerPixel = 1\n \
+ PhotometricInterpretation = MONOCHROME1 \n \
+ Rows = 10\n \
+ Columns = 5\n \
+ BitsAllocated = 8\n \
+ BitsStored = 8\n \
+ HighBit = 7\n \
+ PixelRepresentation = 0\n \
+ RescaleIntercept = 0\n \
+ RescaleSlope = 1\n \
+ RescaleType = US\n \
+ PixelData = not assigned\n \
+@end example\n \
\n\
@seealso{dicomread, dicomdict} \n\
@end deftypefn\n\
@@ -685,9 +737,7 @@ char* name2Keyword (char *d, int *d_len_p, const char* s)
/*
%!shared testfile
-%! testfile = urlwrite ( ...
-%! 'http://sourceforge.net/p/octave/code/11601/tree/trunk/octave-forge/extra/dicom/dcm_examples/RD.15MV.DCM?format=raw', ...
-%! tempname() );
+%! testfile = file_in_loadpath("imdata/simpleImageWithIcon.dcm");
%!fail("dicominfo")
@@ -695,14 +745,9 @@ char* name2Keyword (char *d, int *d_len_p, const char* s)
%!test
%! s=dicominfo(testfile);
-%! assert(s.PatientName,"PHANTOM^IsodoseComparison^^^");
+%! assert(s.PatientName,"GDCM^Patient");
%!test
%! s=dicominfo(testfile);
-%! assert(s.ROIContourSequence.Item_1.ContourSequence.Item_1.ContourGeometricType,"POINT ");
-
-%!test
-%! if exist (testfile, 'file')
-%! delete (testfile);
-%! endif
+%! assert(s.IconImageSequence.Item_1.PhotometricInterpretation,"MONOCHROME2 ");
*/
diff --git a/src/dicomlookup.cpp b/src/dicomlookup.cpp
index 8c2a816..065fc63 100644
--- a/src/dicomlookup.cpp
+++ b/src/dicomlookup.cpp
@@ -53,6 +53,31 @@ of the attribute.\n\
dictionary for a specified @var{keyword} string and returns the @var{group} and @var{element}\n \
for keyword.\n\
\n\
+@subsubheading Inputs\n\
+@var{keyword} - string keyword name to look up a group, element value.@*\n\
+@var{group} - group value to look up (string or integer).@*\n\
+@var{element} - element value to look up (string or integer).@*\n\
+\n\
+@subsubheading Outputs\n\
+@var{keyword} - string keyword name to looked up from a group, element value.@*\n\
+@var{group}, @var{element} - group and element value looked up from keyword.@*\n\
+\n\
+@subsubheading Outputs\n\
+Look up tag name for 0x10 0x10:\n\
+\n\
+@example\n\
+> name = dicomlookup(0x10,0x10)\n\
+name = PatientName\n\
+\n\
+@end example\n\
+\n\
+Look up tag group and element value:\n\
+\n\
+@example\n\
+> [grp, elm] = dicomlookup('TransferSyntaxUID')\n\
+grp = 2\n\
+elm = 16\n\
+@end example\n\
@seealso{dicomdict}\n\
@end deftypefn \n\
")
diff --git a/src/dicomread.cpp b/src/dicomread.cpp
index dec6d4c..31498d2 100644
--- a/src/dicomread.cpp
+++ b/src/dicomread.cpp
@@ -45,10 +45,33 @@ DEFUN_DLD (dicomread, args, nargout,
@deftypefnx {Loadable Function} @var{image} = dicomread (@var{structure}) \n\
\n\
Load the image from a DICOM file. \n\
-@var{filename} is a string (giving the filename).\n\
-@var{structure} is a structure with a field @code{Filename} (such as returned by @code{dicominfo}).\n\
-@var{image} may be two or three dimensional, depending on the content of the file. \n\
-An integer or float matrix will be returned, the number of bits will depend on the file. \n\
+@subsubheading Inputs\n\
+@var{filename} - a string giving the filename.*\n\
+\n\
+@var{structure} - a structure with a field @code{Filename} (such as returned by @code{dicominfo}).\n\
+\n\
+@var{image} - may be two or three dimensional, depending on the content of the file. \n\
+\n\
+@subsubheading Outputs\n\
+@var{image} - An integer or float matrix will be returned, the number of bits will depend on the file. \n\
+\n\
+@subsubheading Examples\n\
+Load the image data of a dcm file:\n\
+\n\
+@example\n\
+> image = dicomread(file_in_load_path('imdata/simple-test.dcm'))\n\
+image =\n\
+ 0 0 0 0 0\n\
+ 0 0 0 0 0\n\
+ 0 0 0 0 0\n\
+ 0 0 0 0 0\n\
+ 0 0 0 0 0\n\
+ 0 0 0 0 0\n\
+ 0 0 0 0 0\n\
+ 0 0 0 0 0\n\
+ 0 0 0 0 0\n\
+ 0 0 0 0 0\n\
+@end example\n\
\n\
@seealso{dicominfo} \n\
@end deftypefn \n\
@@ -190,9 +213,7 @@ An integer or float matrix will be returned, the number of bits will depend on t
/*
%!shared testfile
-%! testfile = urlwrite ( ...
-%! 'http://sourceforge.net/p/octave/code/11601/tree/trunk/octave-forge/extra/dicom/dcm_examples/RD.15MV.DCM?format=raw', ...
-%! tempname() );
+%! testfile = file_in_loadpath("imdata/CT-MONO2-16-ankle.dcm");
%!fail ("dicomread");
%!fail ("dicomread (1)");
@@ -200,15 +221,11 @@ An integer or float matrix will be returned, the number of bits will depend on t
%!test
%! rd=dicomread(testfile);
-%! assert(rd(100,101,30),uint16(2021));
+%! assert(rd(100,101),int16(128));
%!test
%! data={};
%! data.Filename = testfile;
%! rd=dicomread(data);
-%! assert(rd(100,101,30),uint16(2021));
-
-%! if exist (testfile, 'file')
-%! delete (testfile);
-%! endif
+%! assert(rd(100,101),int16(128));
*/
diff --git a/src/dicomuid.cpp b/src/dicomuid.cpp
index 3831788..664d5ae 100644
--- a/src/dicomuid.cpp
+++ b/src/dicomuid.cpp
@@ -39,8 +39,19 @@ DEFUN_DLD (dicomuid, args, nargout,
\n\
Generate a DICOM unique id . \n\
\n \
+@subsubheading Inputs\n\
+None\n\
+@subsubheading Outputs\n\
@var{uuid} is a unique id string.\n\
\n\
+@subsubheading Examples\n\
+Get a new uid:\n\
+\n\
+@example\n\
+> uid = dicomuid ()\n\
+uid = 1.2.826.0.1.3680043.2.1143.3114589836670200378351641061429967573\n\
+@end example\n\
+\n\
@end deftypefn \n\
")
{
diff --git a/src/dicomwrite.cpp b/src/dicomwrite.cpp
index 3ed3c74..0317346 100644
--- a/src/dicomwrite.cpp
+++ b/src/dicomwrite.cpp
@@ -62,9 +62,27 @@ DEFUN_DLD (dicomwrite, args, nargout,
\n\
Write a DICOM format file to @var{filename}.\n\
\n\
-@var{im} is image data or empty matrix, [], if only metadata save is required\n\
-@var{filename} is filename to write dicom to. if [], then function runs in verbose trial mode.\n\
-@var{info} struct, like that produced by dicominfo\n\
+@subsubheading Inputs\n\
+@var{im} - image data or empty matrix, [], if only metadata save is required\n\
+\n\
+@var{filename} - filename to write dicom to. if [], then function runs in verbose trial mode.\n\
+\n\
+@var{info} - struct, like that produced by dicominfo\n\
+\n\
+@subsubheading Examples\n\
+Create a dicom file using default info, and the supplied data:\n\
+@example\n\
+> wdata = uint8 (10*rand (10,10));\n\
+> dicomwrite (wdata, 'test.dcm');\n\
+@end example\n\
+\n\
+Create a dicom file using data and meta info:\n\
+\n\
+@example\n\
+> wdata = dicomread(file_in_loadpath('imdata/CT-MONO2-16-ankle.dcm');\n\
+> info = dicominfo(file_in_loadpath('imdata/CT-MONO2-16-ankle.dcm');\n\
+> dicomwrite(wdata, info);\n\
+@end example\n\
\n\
@seealso{dicomread, dicominfo}\n\
@end deftypefn \n\
diff --git a/src/isdicom.cpp b/src/isdicom.cpp
index da4bdba..4aa551f 100644
--- a/src/isdicom.cpp
+++ b/src/isdicom.cpp
@@ -37,19 +37,27 @@ isdicom (const std::string& filename)
if (!filename.length ())
return false;
+ // we seem to crash for some reason is use a const filename
+ char namebuff[filename.length () + 1];
+ strcpy(namebuff, filename.c_str());
+
gdcm::Reader reader;
- reader.SetFileName (filename.c_str ());
+ reader.SetFileName (namebuff);
- // gdcm::Reader.Read() will return false if the file does not exists but
- // also prints to stderr so we check it first.
- return OCTAVE__FILE_STAT (filename).exists () && reader.Read ();
+ return OCTAVE__FILE_STAT (namebuff).exists () && reader.Read ();
}
DEFUN_DLD (isdicom, args, ,
"-*- texinfo -*- \n\
-@deftypefn {Loadable Function} {} isdicom (@var{filename}) \n\
+@deftypefn {Loadable Function} {@var{yesno} =} isdicom (@var{filename}) \n\
Return true if @var{filename} is a valid DICOM file.\n\
\n\
+@subsubheading Inputs\n\
+@var{filename} - name of file to read.\n\
+\n\
+@subsubheading Outputs\n\
+@var{yesno} - logical value of true if filename is a dicom file.\n\
+\n\
@seealso{dicomdict, dicominfo, dicomread, dicomwrite} \n\
@end deftypefn")
{