1 #include <creaImageIOImageReader.h>
2 #include <creaImageIOTreeAttributeDescriptor.h>
3 #include <creaImageIOSystem.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 GimmickMessage(2,"Reading attributes from '"<<filename<<std::endl);
161 // Get image dimensions
162 // How to get the image info without loading it in vtk ?
163 mVTKReader->SetFileName(filename.c_str());
164 mVTKReader->Update(); //OpenFile();
166 mVTKReader->GetDataExtent(ext);
169 sprintf(cols,"%i",ext[1]-ext[0]);
172 sprintf(rows,"%i",ext[3]-ext[2]);
175 sprintf(planes,"%i",ext[5]-ext[4]);
179 std::map<std::string,std::string>::iterator i;
180 if ( (i = attr.find("FullFileName")) != attr.end())
182 // boost::filesystem::path full_path(filename);
183 // std::string f = full_path.leaf();
184 i->second = filename;
186 if ( (i = attr.find("D0004_1500")) != attr.end())
188 boost::filesystem::path full_path(filename);
189 std::string f = full_path.leaf();
192 if ( (i = attr.find("D0028_0010")) != attr.end())
196 if ( (i = attr.find("D0028_0011")) != attr.end())
201 if ( (i = attr.find("D0028_0012")) != attr.end())
206 GimmickMessage(2,"Attributes map:"<<std::endl<<attr<<std::endl);
208 //=====================================================================
210 vtkImageReader2* mVTKReader;
211 std::string mExtensions;
213 //=====================================================================
215 //=====================================================================
217 void IRFillFields(DicomNode* node,
218 GDCM_NAME_SPACE::File* gdcmFile)
220 const DicomNodeTypeDescription::FieldDescriptionMapType& dm
221 = node->GetTypeDescription().GetFieldDescriptionMap();
222 DicomNodeTypeDescription::FieldDescriptionMapType::const_iterator i;
225 DicomNode::FieldValueMapType& vm = node->GetFieldValueMap();
226 for (i=dm.begin(); i!=dm.end(); ++i)
228 if ( (i->second.flags==0) &&
229 (i->second.group!=0) &&
230 (i->second.element!=0) )
232 uint16_t gr = i->second.group;
233 uint16_t el = i->second.element;
235 std::string val = gdcmFile->GetEntryString(gr,el);
237 vm[i->first] = irclean(val);
246 //=====================================================================
248 //=====================================================================
249 class DicomReader : public SpecificImageReader
252 //=====================================================================
255 mReader = vtkGdcmReader::New();
258 //=====================================================================
263 //=====================================================================
264 bool CanRead(const std::string& filename)
266 // std::cout << "## Reader "<<GetName()
267 //<<" ::CanRead("<<filename<<")"
273 // std::cout << "GDCM_NAME_SPACE = '" << STRINGIFY_SYMBOL(GDCM_NAME_SPACE)
277 GDCM_NAME_SPACE::File* file = GDCM_NAME_SPACE::File::New();
278 file->SetLoadMode( GDCM_NAME_SPACE::LD_ALL);
279 file->SetFileName(filename.c_str());
281 bool ok = file->IsReadable();
285 //=====================================================================
286 vtkImageData* ReadImage(const std::string& filename)
288 // std::cout << "## Reader "<<GetName()
289 //<<" ::Read("<<filename<<")"
292 vtkImageData* im = 0;
295 mReader->SetFileName(filename.c_str());
297 im = vtkImageData::New();
298 im->ShallowCopy(mReader->GetOutput());
302 if (im!=0) im->Delete();
307 //=====================================================================
308 void PushBackExtensions(std::vector<std::string>& v)
313 //=====================================================================
315 //=====================================================================
316 //=====================================================================
317 void ReadAttributes(const std::string& filename,
318 std::map<std::string,std::string>& attr)
320 // std::cout << "DicomReader::ReadDicomInfo '"<<filename<<"'"<<std::endl;
321 GimmickMessage(2,"Reading attributes from DICOM file '"
322 <<filename<<"'"<<std::endl);
324 GDCM_NAME_SPACE::File* file = GDCM_NAME_SPACE::File::New();
325 file->SetLoadMode( GDCM_NAME_SPACE::LD_ALL);
326 file->SetFileName(filename.c_str());
328 if (file->IsReadable())
331 std::map<std::string,std::string>::iterator i;
332 for (i=attr.begin();i!=attr.end();++i)
334 if ( i->first == "D0004_1500" )
336 boost::filesystem::path full_path(filename);
337 std::string f = full_path.leaf();
340 else if ( i->first == "FullFileName" )
342 i->second = filename;
348 tree::AttributeDescriptor::GetDicomGroupElementFromKey(i->first,gr,el);
349 // GimmickMessage(2,"Key '"<<i->first<<"' : "<<gr<<"|"<<el
351 if ( ( gr!=0 ) && ( el!=0 ) )
353 std::string val = file->GetEntryString(gr,el);
354 i->second = irclean(val);
355 // GimmickMessage(2,"Key '"<<i->first<<"' : "<<gr<<"|"<<el
356 // <<"="<<i->second<<std::endl);
366 vtkGdcmReader* mReader;
368 //=====================================================================
374 //=====================================================================
375 ImageReader::ImageReader()
378 mLastFilename("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&"),
382 // std::cout << "#### ImageReader::ImageReader()"<<std::endl;
383 if (mUnreadableImage!=0) return;
385 Register(new SpecificVtkReader(vtkPNGReader::New()));
386 Register(new SpecificVtkReader(vtkTIFFReader::New()));
387 Register(new SpecificVtkReader(vtkJPEGReader::New()));
388 Register(new SpecificVtkReader(vtkBMPReader::New()));
389 Register(new SpecificVtkReader(vtkSLCReader::New()));
390 Register(new SpecificVtkReader(vtkMetaImageReader::New(),"MHD",".mhd"));
391 // Register(new SpecificVtkReader(vtkGESignalReader::New()));
392 Register(new DicomReader);
395 std::cout << "## Registered file extensions : "<<std::endl;
396 std::vector<std::string>::const_iterator i;
397 for (i=GetKnownExtensions().begin();
398 i!=GetKnownExtensions().end();
401 std::cout << "'"<<(*i)<<"'"<<std::endl;
405 mUnreadableImage = vtkImageData::New();
407 dim[0] = dim[1] = 128;
409 mUnreadableImage->SetDimensions ( dim );
410 mUnreadableImage->SetScalarTypeToUnsignedChar();
411 mUnreadableImage->AllocateScalars();
412 for (int i=0;i<dim[0];i++)
413 for (int j=0;j<dim[1];j++)
414 mUnreadableImage->SetScalarComponentFromFloat(i,j,0,0,0);
415 for (int i=0;i<dim[0];i++)
417 mUnreadableImage->SetScalarComponentFromFloat(i,i,0,0,255);
418 mUnreadableImage->SetScalarComponentFromFloat(dim[0]-1-i,i,0,0,255);
424 //=====================================================================
426 //=====================================================================
427 ImageReader::~ImageReader()
429 // std::cout << "#### ImageReader::~ImageReader()"<<std::endl;
430 std::vector<SpecificImageReader*>::iterator i;
431 for (i=mReader.begin(); i!=mReader.end(); i++)
433 // std::cout << "#### ImageReader::UnRegister("
434 // << (*i)->GetName()<<")"<<std::endl;
438 if (mUnreadableImage!=0)
440 mUnreadableImage->Delete();
441 mUnreadableImage = 0;
444 //=====================================================================
446 //=====================================================================
447 void ImageReader::Register(SpecificImageReader* r)
449 // std::cout << "#### ImageReader::Register("<<r->GetName()<<")"<<std::endl;
450 mReader.push_back(r);
451 r->PushBackExtensions(mKnownExtensions);
453 //=====================================================================
455 //=====================================================================
456 // Returns true iff the file is readable
457 bool ImageReader::CanRead( const std::string& filename,
458 const std::string& exclude )
460 // std::cout << "## ImageReader::CanRead("<<filename<<")"<<std::endl;
462 std::vector<SpecificImageReader*>::iterator i;
463 for (i=mReader.begin(); i!=mReader.end(); i++)
465 if ((*i)->GetName()==exclude) continue;
466 ok = (*i)->CanRead(filename);
469 mLastFilename = filename;
476 //=====================================================================
478 //=====================================================================
479 // Reads the file (CanRead must be called before : no test here)
480 vtkImageData* ImageReader::ReadImage( const std::string& filename,
481 const std::string& exclude )
483 // std::cout << "## ImageReader::Read("<<filename<<")"<<std::endl;
484 if (mLastFilename!=filename)
486 if (!CanRead(filename,exclude))
488 // std::cout << " -- Cannot read image "<<std::endl;
489 vtkImageData* im = vtkImageData::New();
490 im->ShallowCopy(mUnreadableImage);
494 vtkImageData* i = mLastReader->ReadImage(mLastFilename);
495 // std::cout << "i="<<i<<std::endl;
498 // std::cout << "i=UNREAD"<<i<<std::endl;
499 i = vtkImageData::New();
500 i->ShallowCopy(mUnreadableImage);
502 // std::cout << "i="<<i<<std::endl;
505 //=====================================================================
508 //=====================================================================
509 void ImageReader::ReadAttributes(const std::string& filename,
510 std::map<std::string,std::string>& attr)
512 // std::cout << "ImageReader::ReadDicomInfo '"<<filename<<"'"<<std::endl;
513 // std::cout << "## ImageReader::Read("<<filename<<")"<<std::endl;
514 if (mLastFilename!=filename)
516 if (!CanRead(filename))
521 mLastReader->ReadAttributes(mLastFilename,attr);
523 //=====================================================================
527 } // namespace creaImageIO