1 /* 2 * The GNU Octave dicom package is Copyright Andy Buckle 2010 3 * Contact: blondandy using the sf.net system, 4 * <https://sourceforge.net/sendmessage.php?touser=1760416> 5 * 6 * Changes Copyright Kris Thielemans 2011: 7 * - support usage dicomread(struct-returned-by-dicominfo) 8 * - return image in same order as matlab 9 * 10 * The GNU Octave dicom package is free software: you can redistribute 11 * it and/or modify it under the terms of the GNU General Public 12 * License as published by the Free Software Foundation, either 13 * version 3 of the License, or (at your option) any later version. 14 * 15 * The GNU Octave dicom package is distributed in the hope that it 16 * will be useful, but WITHOUT ANY WARRANTY; without even the 17 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 18 * PURPOSE. See the GNU General Public License for more details. 19 * 20 * Please see the file, "COPYING" for further details of GNU General 21 * Public License version 3. 22 * 23 */ 24 25 #include "octave/oct.h" 26 #include <octave/ov-struct.h> 27 28 #ifdef HAVE_CONFIG_H 29 #include "config.h" 30 #endif 31 32 #include "gdcmImageReader.h" 33 using namespace gdcm; 34 35 #define DICOM_ERR -1 36 #define DICOM_OK 0 37 38 #define OCT_FN_NAME dicomread 39 #define QUOTED_(x) #x 40 #define QUOTED(x) QUOTED_(x) 41 42 DEFUN_DLD (dicomread, args, nargout, 43 "-*- texinfo -*- \n\ 44 @deftypefn {Loadable Function} @var{image} = dicomread (@var{filename}) \n\ 45 @deftypefnx {Loadable Function} @var{image} = dicomread (@var{structure}) \n\ 46 \n\ 47 Load the image from a DICOM file. \n\ 48 @var{filename} is a string (giving the filename).\n\ 49 @var{structure} is a structure with a field @code{Filename} (such as returned by @code{dicominfo}).\n\ 50 @var{image} may be two or three dimensional, depending on the content of the file. \n\ 51 An integer or float matrix will be returned, the number of bits will depend on the file. \n\ 52 \n\ 53 @seealso{dicominfo} \n\ 54 @end deftypefn \n\ 55 ") 56 { 57 octave_value_list retval; // create object to store return values 58 if ( 0 == args.length()) 59 { 60 error (QUOTED(OCT_FN_NAME)": one arg required: dicom filename"); 61 return retval; 62 } 63 64 std::string filename; 65 // argument processing 66 // check if 1st argument is a string or a struct with field Filename 67 // If so, assign to filename variable, otherwise exit. 68 if (args(0).is_string ()) 69 { 70 filename = args(0).string_value(); 71 } 72 else 73 { 74 if (! args(0).OV_ISMAP ()) 75 { 76 error(QUOTED(OCT_FN_NAME)": arg should be a filename, 1 row of chars, or a struct returned by dicominfo"); 77 return retval; 78 } 79 octave_scalar_map arg0 = args(0).scalar_map_value (); 80 if (!arg0.contains("Filename")) 81 { 82 error (QUOTED(OCT_FN_NAME)": if arg is a struct, it should have the Filename field"); 83 return retval; 84 } 85 octave_value tmp = arg0.getfield ("Filename"); 86 filename = tmp.string_value(); 87 } 88 89 #if 0 /* TODO support 'frames' stuff, see Matlab docs for dicomread */ 90 int i; // parse any additional args 91 for (i=1; i<args.length(); i++) 92 { 93 charMatrix chex = args(i).char_matrix_value(); 94 if (chex.rows() != 1) 95 { 96 error (QUOTED(OCT_FN_NAME)": arg should be a string, 1 row of chars"); 97 return retval; 98 } 99 } 100 #endif 101 102 gdcm::ImageReader reader; 103 reader.SetFileName (filename.c_str()); 104 if (!reader.Read()) 105 { 106 error (QUOTED(OCT_FN_NAME)": Could not read DICOM file with image: %s",filename.c_str()); 107 return retval; 108 } 109 110 const gdcm::Image &image = reader.GetImage(); 111 112 const octave_idx_type ndim = image.GetNumberOfDimensions(); 113 const unsigned int * const dims = image.GetDimensions(); 114 // dim 0: cols (width) 115 // dim 1: rows (height) 116 // dim 2: number of frames 117 118 dim_vector dv; 119 Array<octave_idx_type> perm_vect(dim_vector(ndim,1)); 120 perm_vect(0) = 1; 121 perm_vect(1) = 0; 122 123 // TODO check with non-square images if this needs to be dims[1],dims[0] etc 124 if( 2 == ndim ) 125 { 126 //this transposes first two dimensions 127 dv = dim_vector(octave_idx_type(dims[0]), octave_idx_type(dims[1])); 128 } 129 else if (3 == ndim) 130 { 131 // should be (rows, cols, pages) in octave idiom 132 dv = dim_vector(octave_idx_type(dims[0]), octave_idx_type(dims[1]), octave_idx_type(dims[2])); 133 perm_vect(2) = 2; 134 } 135 else 136 { 137 error(QUOTED(OCT_FN_NAME)": %i dimensions. not supported: %s",(int)ndim, filename.c_str()); 138 return retval; 139 } 140 141 if (gdcm::PixelFormat::UINT32 == image.GetPixelFormat()) 142 { 143 //tested 144 uint32NDArray arr(dv); 145 image.GetBuffer ((char *)arr.fortran_vec()); 146 return octave_value (arr.permute(perm_vect)); 147 } 148 else if ( gdcm::PixelFormat::UINT16 == image.GetPixelFormat() ) 149 { 150 //tested 151 uint16NDArray arr(dv); 152 image.GetBuffer ((char *)arr.fortran_vec()); 153 return octave_value (arr.permute(perm_vect)); 154 } 155 else if ( gdcm::PixelFormat::UINT8 == image.GetPixelFormat() ) 156 { 157 //tested 158 uint8NDArray arr(dv); 159 image.GetBuffer ((char *)arr.fortran_vec()); 160 return octave_value (arr.permute(perm_vect)); 161 } 162 else if ( gdcm::PixelFormat::INT8 == image.GetPixelFormat() ) 163 { 164 // no example found to test 165 int8NDArray arr(dv); 166 image.GetBuffer((char *)arr.fortran_vec()); 167 return octave_value(arr.permute(perm_vect)); 168 } 169 else if ( gdcm::PixelFormat::INT16 == image.GetPixelFormat() ) 170 { 171 // no example found to test 172 int16NDArray arr(dv); 173 image.GetBuffer((char *)arr.fortran_vec()); 174 return octave_value(arr.permute(perm_vect)); 175 } 176 else if ( gdcm::PixelFormat::INT32 == image.GetPixelFormat() ) 177 { 178 // no example found to test 179 int32NDArray arr(dv); 180 image.GetBuffer((char *)arr.fortran_vec()); 181 return octave_value(arr.permute(perm_vect)); 182 } 183 else 184 { 185 octave_stdout << image.GetPixelFormat() << '\n' ; 186 error(QUOTED(OCT_FN_NAME)": pixel format not supported yet: %s", filename.c_str()); 187 return retval; 188 } 189 } 190 191 /* 192 %!shared testfile 193 %! testfile = urlwrite ( ... 194 %! 'http://sourceforge.net/p/octave/code/11601/tree/trunk/octave-forge/extra/dicom/dcm_examples/RD.15MV.DCM?format=raw', ... 195 %! tempname() ); 196 197 %!fail ("dicomread"); 198 %!fail ("dicomread (1)"); 199 %!fail ("dicomread ('hopefully_a_non_existant_file')"); 200 201 %!test 202 %! rd=dicomread(testfile); 203 %! assert(rd(100,101,30),uint16(2021)); 204 205 %!test 206 %! data={}; 207 %! data.Filename = testfile; 208 %! rd=dicomread(data); 209 %! assert(rd(100,101,30),uint16(2021)); 210 211 %! if exist (testfile, 'file') 212 %! delete (testfile); 213 %! endif 214 */ 215