1 #include <creaImageIOImageReader.h>
2 //#include <creaImageIOUtilities.h>
5 #include <vtkImageReader2.h>
6 #include <vtkPNGReader.h>
7 #include <vtkTIFFReader.h>
8 #include <vtkJPEGReader.h>
9 #include <vtkBMPReader.h>
10 #include <vtkSLCReader.h>
11 #include <vtkMetaImageReader.h>
12 //#include <vtkGESignalReader.h>
15 #include <vtkGdcmReader.h>
18 #include "boost/filesystem/path.hpp"
23 //========================================================================
24 std::string irclean(const std::string& str)
26 if (str == "GDCM::Unfound")
30 if (str[str.size()-1]==' ')
32 return str.substr(0,str.size()-1);
34 if (str[str.size()-1]==0)
36 return str.substr(0,str.size()-1);
41 //========================================================================
43 void IRSplitString ( const std::string& str,
44 const std::string& delimiters,
45 std::vector<std::string>& tokens)
47 // Skip delimiters at beginning.
48 std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
49 // Find first delimiter.
50 std::string::size_type pos = str.find_first_of(delimiters, lastPos);
52 while (std::string::npos != pos || std::string::npos != lastPos)
54 // Found a token, add it to the vector.
55 // SPECIFIC : REMOVE INITIAL DOT (lastPos + 1)
56 tokens.push_back(str.substr(lastPos+1, pos - lastPos));
57 // Skip delimiters. Note the "not_of"
58 lastPos = str.find_first_not_of(delimiters, pos);
59 // Find next delimiter
60 pos = str.find_first_of(delimiters, lastPos);
65 //=====================================================================
68 std::vector<SpecificImageReader*> ImageReader::mReader;
69 std::vector<std::string>ImageReader::mKnownExtensions;
70 vtkImageData* ImageReader::mUnreadableImage = 0;
71 std::string ImageReader::mLastFilename("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&");
72 SpecificImageReader* ImageReader::mLastReader = 0;
73 //=====================================================================
74 // Global instance : automatic init / destr
75 ImageReader GlobalImageReader;
76 //=====================================================================
79 //=====================================================================
80 class SpecificImageReader
83 SpecificImageReader() {}
84 virtual ~SpecificImageReader() {}
85 void SetName(const std::string& s) { mName = s; }
86 const std::string& GetName() const { return mName; }
87 virtual bool CanRead(const std::string& filename) { return false; }
88 virtual vtkImageData* Read(const std::string& filename) { return 0; }
89 virtual void PushBackExtensions(std::vector<std::string>&) {}
90 virtual void ReadDicomInfo(const std::string& filename,
95 //=====================================================================
97 //=====================================================================
98 class SpecificVtkReader : public SpecificImageReader
101 SpecificVtkReader(vtkImageReader2* r,
102 const std::string& name = "",
103 const std::string& extensions = "")
104 : mVTKReader(r), mExtensions(extensions)
106 if (name.size() == 0)
108 SetName ( mVTKReader->GetDescriptiveName() );
117 mVTKReader->Delete();
119 bool CanRead(const std::string& filename)
121 // std::cout << "## Reader "<<GetName()
122 //<<" ::CanRead("<<filename<<")"
124 return (mVTKReader->CanReadFile(filename.c_str())!=0);
126 vtkImageData* Read(const std::string& filename)
128 // std::cout << "## Reader "<<GetName()
129 //<<" ::Read("<<filename<<")"
131 vtkImageData* im = 0;
134 mVTKReader->SetFileName(filename.c_str());
135 mVTKReader->Update();
136 im = vtkImageData::New();
137 im->ShallowCopy(mVTKReader->GetOutput());
141 if (im!=0) im->Delete();
147 void PushBackExtensions(std::vector<std::string>& v)
149 std::string ext = mExtensions;
150 if (ext.size()==0) ext = mVTKReader->GetFileExtensions ();
152 IRSplitString(ext," ",v);
155 void ReadDicomInfo(const std::string& filename,
158 // std::cout << "SpecificVtkReader::ReadDicomInfo '"<<filename<<"'"<<std::endl;
159 boost::filesystem::path full_path(filename);
160 std::string f = full_path.leaf();
161 //Utilities::GetFileName(filename));
163 image->SetFieldValue("A0004_1500",irclean(f));
165 // How to get the image info without loading it in vtk ?
167 mVTKReader->SetFileName(filename.c_str());
168 mVTKReader->Update(); //OpenFile();
170 mVTKReader->GetDataExtent(ext);
173 sprintf(str,"%i",ext[1]-ext[0]);
174 // std::cout << "col="<<str<<std::endl;
175 image->SetFieldValue("A0028_0011",str);
177 sprintf(str,"%i",ext[3]-ext[2]);
178 // std::cout << "row="<<str<<std::endl;
179 image->SetFieldValue("A0028_0010",str);
181 sprintf(str,"%i",ext[5]-ext[4]);
182 // std::cout << "frames="<<str<<std::endl;
183 image->SetFieldValue("A0028_0008",str);
187 vtkImageReader2* mVTKReader;
188 std::string mExtensions;
190 //=====================================================================
192 //=====================================================================
193 void IRFillFields(DicomNode* node,
194 GDCM_NAME_SPACE::File* gdcmFile)
196 const DicomNodeTypeDescription::FieldDescriptionMapType& dm
197 = node->GetTypeDescription().GetFieldDescriptionMap();
198 DicomNodeTypeDescription::FieldDescriptionMapType::const_iterator i;
201 DicomNode::FieldValueMapType& vm = node->GetFieldValueMap();
202 for (i=dm.begin(); i!=dm.end(); ++i)
204 if ( (i->second.flags==0) &&
205 (i->second.group!=0) &&
206 (i->second.element!=0) )
208 uint16_t gr = i->second.group;
209 uint16_t el = i->second.element;
211 std::string val = gdcmFile->GetEntryString(gr,el);
213 vm[i->first] = irclean(val);
221 //=====================================================================
223 //=====================================================================
224 class DicomReader : public SpecificImageReader
229 mReader = vtkGdcmReader::New();
236 bool CanRead(const std::string& filename)
238 // std::cout << "## Reader "<<GetName()
239 //<<" ::CanRead("<<filename<<")"
245 // std::cout << "GDCM_NAME_SPACE = '" << STRINGIFY_SYMBOL(GDCM_NAME_SPACE)
249 GDCM_NAME_SPACE::File* file = GDCM_NAME_SPACE::File::New();
250 file->SetLoadMode( GDCM_NAME_SPACE::LD_ALL);
251 file->SetFileName(filename.c_str());
253 bool ok = file->IsReadable();
257 vtkImageData* Read(const std::string& filename)
259 // std::cout << "## Reader "<<GetName()
260 //<<" ::Read("<<filename<<")"
263 vtkImageData* im = 0;
266 mReader->SetFileName(filename.c_str());
268 im = vtkImageData::New();
269 im->ShallowCopy(mReader->GetOutput());
273 if (im!=0) im->Delete();
279 void PushBackExtensions(std::vector<std::string>& v)
285 void ReadDicomInfo(const std::string& filename,
288 // std::cout << "DicomReader::ReadDicomInfo '"<<filename<<"'"<<std::endl;
289 GDCM_NAME_SPACE::File* file = GDCM_NAME_SPACE::File::New();
290 file->SetLoadMode( GDCM_NAME_SPACE::LD_ALL);
291 file->SetFileName(filename.c_str());
293 if (file->IsReadable())
296 DicomNode* cur = image;
299 IRFillFields(cur,file);
300 cur = cur->GetParent();
303 // File name and full file name
304 image->SetFieldValue("FullFileName",filename);
306 boost::filesystem::path full_path(filename);
308 image->SetFieldValue("A0004_1500",full_path.leaf());
309 //Utilities::GetFileName(filename));
316 vtkGdcmReader* mReader;
318 //=====================================================================
324 //=====================================================================
325 ImageReader::ImageReader()
328 mLastFilename("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&"),
332 // std::cout << "#### ImageReader::ImageReader()"<<std::endl;
333 if (mUnreadableImage!=0) return;
335 Register(new SpecificVtkReader(vtkPNGReader::New()));
336 Register(new SpecificVtkReader(vtkTIFFReader::New()));
337 Register(new SpecificVtkReader(vtkJPEGReader::New()));
338 Register(new SpecificVtkReader(vtkBMPReader::New()));
339 Register(new SpecificVtkReader(vtkSLCReader::New()));
340 Register(new SpecificVtkReader(vtkMetaImageReader::New(),"MHD",".mhd"));
341 // Register(new SpecificVtkReader(vtkGESignalReader::New()));
342 Register(new DicomReader);
345 std::cout << "## Registered file extensions : "<<std::endl;
346 std::vector<std::string>::const_iterator i;
347 for (i=GetKnownExtensions().begin();
348 i!=GetKnownExtensions().end();
351 std::cout << "'"<<(*i)<<"'"<<std::endl;
355 mUnreadableImage = vtkImageData::New();
357 dim[0] = dim[1] = 128;
359 mUnreadableImage->SetDimensions ( dim );
360 mUnreadableImage->SetScalarTypeToUnsignedChar();
361 mUnreadableImage->AllocateScalars();
362 for (int i=0;i<dim[0];i++)
363 for (int j=0;j<dim[1];j++)
364 mUnreadableImage->SetScalarComponentFromFloat(i,j,0,0,0);
365 for (int i=0;i<dim[0];i++)
367 mUnreadableImage->SetScalarComponentFromFloat(i,i,0,0,255);
368 mUnreadableImage->SetScalarComponentFromFloat(dim[0]-1-i,i,0,0,255);
374 //=====================================================================
376 //=====================================================================
377 ImageReader::~ImageReader()
379 // std::cout << "#### ImageReader::~ImageReader()"<<std::endl;
380 std::vector<SpecificImageReader*>::iterator i;
381 for (i=mReader.begin(); i!=mReader.end(); i++)
383 // std::cout << "#### ImageReader::UnRegister("
384 // << (*i)->GetName()<<")"<<std::endl;
388 if (mUnreadableImage!=0)
390 mUnreadableImage->Delete();
391 mUnreadableImage = 0;
394 //=====================================================================
396 //=====================================================================
397 void ImageReader::Register(SpecificImageReader* r)
399 // std::cout << "#### ImageReader::Register("<<r->GetName()<<")"<<std::endl;
400 mReader.push_back(r);
401 r->PushBackExtensions(mKnownExtensions);
403 //=====================================================================
405 //=====================================================================
406 // Returns true iff the file is readable
407 bool ImageReader::CanRead( const std::string& filename,
408 const std::string& exclude )
410 // std::cout << "## ImageReader::CanRead("<<filename<<")"<<std::endl;
412 std::vector<SpecificImageReader*>::iterator i;
413 for (i=mReader.begin(); i!=mReader.end(); i++)
415 if ((*i)->GetName()==exclude) continue;
416 ok = (*i)->CanRead(filename);
419 mLastFilename = filename;
426 //=====================================================================
428 //=====================================================================
429 // Reads the file (CanRead must be called before : no test here)
430 vtkImageData* ImageReader::Read( const std::string& filename,
431 const std::string& exclude )
433 // std::cout << "## ImageReader::Read("<<filename<<")"<<std::endl;
434 if (mLastFilename!=filename)
436 if (!CanRead(filename,exclude))
438 // std::cout << " -- Cannot read image "<<std::endl;
439 vtkImageData* im = vtkImageData::New();
440 im->ShallowCopy(mUnreadableImage);
444 vtkImageData* i = mLastReader->Read(mLastFilename);
445 // std::cout << "i="<<i<<std::endl;
448 // std::cout << "i=UNREAD"<<i<<std::endl;
449 i = vtkImageData::New();
450 i->ShallowCopy(mUnreadableImage);
452 // std::cout << "i="<<i<<std::endl;
455 //=====================================================================
458 //=====================================================================
459 void ImageReader::ReadDicomInfo(const std::string& filename,
462 // std::cout << "ImageReader::ReadDicomInfo '"<<filename<<"'"<<std::endl;
463 // std::cout << "## ImageReader::Read("<<filename<<")"<<std::endl;
464 if (mLastFilename!=filename)
466 if (!CanRead(filename))
471 mLastReader->ReadDicomInfo(mLastFilename,image);
473 //=====================================================================
477 } // namespace creaImageIO