1 #include <creaImageIOImageReader.h>
2 #include <creaImageIOTreeAttributeDescriptor.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);
66 //=====================================================================
67 class SpecificImageReader
70 SpecificImageReader() {}
71 virtual ~SpecificImageReader() {}
73 void SetName(const std::string& s) { mName = s; }
74 const std::string& GetName() const { return mName; }
76 virtual void PushBackExtensions(std::vector<std::string>&) {}
78 virtual bool CanRead(const std::string& filename) { return false; }
79 virtual vtkImageData* ReadImage(const std::string& filename) { return 0; }
80 virtual void ReadAttributes(const std::string& filename,
81 std::map<std::string,std::string>& attr) {}
86 //=====================================================================
88 //=====================================================================
89 class SpecificVtkReader : public SpecificImageReader
92 //=====================================================================
93 SpecificVtkReader(vtkImageReader2* r,
94 const std::string& name = "",
95 const std::string& extensions = "")
96 : mVTKReader(r), mExtensions(extensions)
100 SetName ( mVTKReader->GetDescriptiveName() );
107 //=====================================================================
110 mVTKReader->Delete();
112 //=====================================================================
113 bool CanRead(const std::string& filename)
115 // std::cout << "## Reader "<<GetName()
116 //<<" ::CanRead("<<filename<<")"
118 return (mVTKReader->CanReadFile(filename.c_str())!=0);
120 //=====================================================================
122 //=====================================================================
123 vtkImageData* ReadImage(const std::string& filename)
125 // std::cout << "## Reader "<<GetName()
126 //<<" ::Read("<<filename<<")"
128 vtkImageData* im = 0;
131 mVTKReader->SetFileName(filename.c_str());
132 mVTKReader->Update();
133 im = vtkImageData::New();
134 im->ShallowCopy(mVTKReader->GetOutput());
138 if (im!=0) im->Delete();
143 //=====================================================================
145 //=====================================================================
146 void PushBackExtensions(std::vector<std::string>& v)
148 std::string ext = mExtensions;
149 if (ext.size()==0) ext = mVTKReader->GetFileExtensions ();
151 IRSplitString(ext," ",v);
153 //=====================================================================
155 //=====================================================================
156 void ReadAttributes(const std::string& filename,
157 std::map<std::string,std::string>& attr)
159 // std::cout << "SpecificVtkReader::ReadDicomInfo '"<<filename<<"'"<<std::endl;
160 // Get image dimensions
161 // How to get the image info without loading it in vtk ?
162 mVTKReader->SetFileName(filename.c_str());
163 mVTKReader->Update(); //OpenFile();
165 mVTKReader->GetDataExtent(ext);
168 sprintf(cols,"%i",ext[1]-ext[0]);
171 sprintf(rows,"%i",ext[3]-ext[2]);
174 sprintf(planes,"%i",ext[5]-ext[4]);
177 std::map<std::string,std::string>::iterator i;
178 if ( (i = attr.find("Full File Name")) != attr.end())
180 boost::filesystem::path full_path(filename);
181 std::string f = full_path.leaf();
184 if ( (i = attr.find("Columns")) != attr.end())
188 if ( (i = attr.find("Rows")) != attr.end())
192 if ( (i = attr.find("Planes")) != attr.end())
197 //=====================================================================
199 vtkImageReader2* mVTKReader;
200 std::string mExtensions;
202 //=====================================================================
204 //=====================================================================
206 void IRFillFields(DicomNode* node,
207 GDCM_NAME_SPACE::File* gdcmFile)
209 const DicomNodeTypeDescription::FieldDescriptionMapType& dm
210 = node->GetTypeDescription().GetFieldDescriptionMap();
211 DicomNodeTypeDescription::FieldDescriptionMapType::const_iterator i;
214 DicomNode::FieldValueMapType& vm = node->GetFieldValueMap();
215 for (i=dm.begin(); i!=dm.end(); ++i)
217 if ( (i->second.flags==0) &&
218 (i->second.group!=0) &&
219 (i->second.element!=0) )
221 uint16_t gr = i->second.group;
222 uint16_t el = i->second.element;
224 std::string val = gdcmFile->GetEntryString(gr,el);
226 vm[i->first] = irclean(val);
235 //=====================================================================
237 //=====================================================================
238 class DicomReader : public SpecificImageReader
241 //=====================================================================
244 mReader = vtkGdcmReader::New();
247 //=====================================================================
252 //=====================================================================
253 bool CanRead(const std::string& filename)
255 // std::cout << "## Reader "<<GetName()
256 //<<" ::CanRead("<<filename<<")"
262 // std::cout << "GDCM_NAME_SPACE = '" << STRINGIFY_SYMBOL(GDCM_NAME_SPACE)
266 GDCM_NAME_SPACE::File* file = GDCM_NAME_SPACE::File::New();
267 file->SetLoadMode( GDCM_NAME_SPACE::LD_ALL);
268 file->SetFileName(filename.c_str());
270 bool ok = file->IsReadable();
274 //=====================================================================
275 vtkImageData* ReadImage(const std::string& filename)
277 // std::cout << "## Reader "<<GetName()
278 //<<" ::Read("<<filename<<")"
281 vtkImageData* im = 0;
284 mReader->SetFileName(filename.c_str());
286 im = vtkImageData::New();
287 im->ShallowCopy(mReader->GetOutput());
291 if (im!=0) im->Delete();
296 //=====================================================================
297 void PushBackExtensions(std::vector<std::string>& v)
302 //=====================================================================
304 //=====================================================================
305 //=====================================================================
306 void ReadAttributes(const std::string& filename,
307 std::map<std::string,std::string>& attr)
309 // std::cout << "DicomReader::ReadDicomInfo '"<<filename<<"'"<<std::endl;
310 GDCM_NAME_SPACE::File* file = GDCM_NAME_SPACE::File::New();
311 file->SetLoadMode( GDCM_NAME_SPACE::LD_ALL);
312 file->SetFileName(filename.c_str());
314 if (file->IsReadable())
317 std::map<std::string,std::string>::iterator i;
318 for (i=attr.begin();i!=attr.end();++i)
320 if ( i->first == "Full File Name" )
322 boost::filesystem::path full_path(filename);
323 std::string f = full_path.leaf();
328 tree::AttributeDescriptor a(i->first);
329 uint16_t gr = a.GetGroup();
330 uint16_t el = a.GetElement();
331 if ( ( gr!=0 ) && ( el!=0 ) )
333 std::string val = file->GetEntryString(gr,el);
334 i->second = irclean(val);
344 vtkGdcmReader* mReader;
346 //=====================================================================
352 //=====================================================================
353 ImageReader::ImageReader()
356 mLastFilename("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&"),
360 // std::cout << "#### ImageReader::ImageReader()"<<std::endl;
361 if (mUnreadableImage!=0) return;
363 Register(new SpecificVtkReader(vtkPNGReader::New()));
364 Register(new SpecificVtkReader(vtkTIFFReader::New()));
365 Register(new SpecificVtkReader(vtkJPEGReader::New()));
366 Register(new SpecificVtkReader(vtkBMPReader::New()));
367 Register(new SpecificVtkReader(vtkSLCReader::New()));
368 Register(new SpecificVtkReader(vtkMetaImageReader::New(),"MHD",".mhd"));
369 // Register(new SpecificVtkReader(vtkGESignalReader::New()));
370 Register(new DicomReader);
373 std::cout << "## Registered file extensions : "<<std::endl;
374 std::vector<std::string>::const_iterator i;
375 for (i=GetKnownExtensions().begin();
376 i!=GetKnownExtensions().end();
379 std::cout << "'"<<(*i)<<"'"<<std::endl;
383 mUnreadableImage = vtkImageData::New();
385 dim[0] = dim[1] = 128;
387 mUnreadableImage->SetDimensions ( dim );
388 mUnreadableImage->SetScalarTypeToUnsignedChar();
389 mUnreadableImage->AllocateScalars();
390 for (int i=0;i<dim[0];i++)
391 for (int j=0;j<dim[1];j++)
392 mUnreadableImage->SetScalarComponentFromFloat(i,j,0,0,0);
393 for (int i=0;i<dim[0];i++)
395 mUnreadableImage->SetScalarComponentFromFloat(i,i,0,0,255);
396 mUnreadableImage->SetScalarComponentFromFloat(dim[0]-1-i,i,0,0,255);
402 //=====================================================================
404 //=====================================================================
405 ImageReader::~ImageReader()
407 // std::cout << "#### ImageReader::~ImageReader()"<<std::endl;
408 std::vector<SpecificImageReader*>::iterator i;
409 for (i=mReader.begin(); i!=mReader.end(); i++)
411 // std::cout << "#### ImageReader::UnRegister("
412 // << (*i)->GetName()<<")"<<std::endl;
416 if (mUnreadableImage!=0)
418 mUnreadableImage->Delete();
419 mUnreadableImage = 0;
422 //=====================================================================
424 //=====================================================================
425 void ImageReader::Register(SpecificImageReader* r)
427 // std::cout << "#### ImageReader::Register("<<r->GetName()<<")"<<std::endl;
428 mReader.push_back(r);
429 r->PushBackExtensions(mKnownExtensions);
431 //=====================================================================
433 //=====================================================================
434 // Returns true iff the file is readable
435 bool ImageReader::CanRead( const std::string& filename,
436 const std::string& exclude )
438 // std::cout << "## ImageReader::CanRead("<<filename<<")"<<std::endl;
440 std::vector<SpecificImageReader*>::iterator i;
441 for (i=mReader.begin(); i!=mReader.end(); i++)
443 if ((*i)->GetName()==exclude) continue;
444 ok = (*i)->CanRead(filename);
447 mLastFilename = filename;
454 //=====================================================================
456 //=====================================================================
457 // Reads the file (CanRead must be called before : no test here)
458 vtkImageData* ImageReader::ReadImage( const std::string& filename,
459 const std::string& exclude )
461 // std::cout << "## ImageReader::Read("<<filename<<")"<<std::endl;
462 if (mLastFilename!=filename)
464 if (!CanRead(filename,exclude))
466 // std::cout << " -- Cannot read image "<<std::endl;
467 vtkImageData* im = vtkImageData::New();
468 im->ShallowCopy(mUnreadableImage);
472 vtkImageData* i = mLastReader->ReadImage(mLastFilename);
473 // std::cout << "i="<<i<<std::endl;
476 // std::cout << "i=UNREAD"<<i<<std::endl;
477 i = vtkImageData::New();
478 i->ShallowCopy(mUnreadableImage);
480 // std::cout << "i="<<i<<std::endl;
483 //=====================================================================
486 //=====================================================================
487 void ImageReader::ReadAttributes(const std::string& filename,
488 std::map<std::string,std::string>& attr)
490 // std::cout << "ImageReader::ReadDicomInfo '"<<filename<<"'"<<std::endl;
491 // std::cout << "## ImageReader::Read("<<filename<<")"<<std::endl;
492 if (mLastFilename!=filename)
494 if (!CanRead(filename))
499 mLastReader->ReadAttributes(mLastFilename,attr);
501 //=====================================================================
505 } // namespace creaImageIO