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 boost::filesystem::path full_path(filename);
159 std::string f = full_path.leaf();
160 //Utilities::GetFileName(filename));
162 image->SetFieldValue("A0004_1500",irclean(f));
164 // How to get the image info without loading it in vtk ?
166 mVTKReader->SetFileName(filename.c_str());
167 mVTKReader->OpenFile();
169 mVTKReader->GetDataExtent(ext);
172 sprintf(str,"%i",ext[1]-ext[0]);
173 image->SetFieldValue("A0028_0011",str);
175 sprintf(str,"%i",ext[3]-ext[2]);
176 image->SetFieldValue("A0028_0010",str);
181 vtkImageReader2* mVTKReader;
182 std::string mExtensions;
184 //=====================================================================
186 //=====================================================================
187 void IRFillFields(DicomNode* node,
188 GDCM_NAME_SPACE::File* gdcmFile)
190 const DicomNodeTypeDescription::FieldDescriptionMapType& dm
191 = node->GetTypeDescription().GetFieldDescriptionMap();
192 DicomNodeTypeDescription::FieldDescriptionMapType::const_iterator i;
195 DicomNode::FieldValueMapType& vm = node->GetFieldValueMap();
196 for (i=dm.begin(); i!=dm.end(); ++i)
198 if ( (i->second.flags==0) &&
199 (i->second.group!=0) &&
200 (i->second.element!=0) )
202 uint16_t gr = i->second.group;
203 uint16_t el = i->second.element;
205 std::string val = gdcmFile->GetEntryString(gr,el);
207 vm[i->first] = irclean(val);
215 //=====================================================================
217 //=====================================================================
218 class DicomReader : public SpecificImageReader
223 mReader = vtkGdcmReader::New();
230 bool CanRead(const std::string& filename)
232 // std::cout << "## Reader "<<GetName()
233 //<<" ::CanRead("<<filename<<")"
239 // std::cout << "GDCM_NAME_SPACE = '" << STRINGIFY_SYMBOL(GDCM_NAME_SPACE)
243 GDCM_NAME_SPACE::File* file = GDCM_NAME_SPACE::File::New();
244 file->SetLoadMode( GDCM_NAME_SPACE::LD_ALL);
245 file->SetFileName(filename.c_str());
247 bool ok = file->IsReadable();
251 vtkImageData* Read(const std::string& filename)
253 // std::cout << "## Reader "<<GetName()
254 //<<" ::Read("<<filename<<")"
257 vtkImageData* im = 0;
260 mReader->SetFileName(filename.c_str());
262 im = vtkImageData::New();
263 im->ShallowCopy(mReader->GetOutput());
267 if (im!=0) im->Delete();
273 void PushBackExtensions(std::vector<std::string>& v)
279 void ReadDicomInfo(const std::string& filename,
282 GDCM_NAME_SPACE::File* file = GDCM_NAME_SPACE::File::New();
283 file->SetLoadMode( GDCM_NAME_SPACE::LD_ALL);
284 file->SetFileName(filename.c_str());
286 if (file->IsReadable())
289 DicomNode* cur = image;
292 IRFillFields(cur,file);
293 cur = cur->GetParent();
296 // File name and full file name
297 image->SetFieldValue("FullFileName",filename);
299 boost::filesystem::path full_path(filename);
301 image->SetFieldValue("A0004_1500",full_path.leaf());
302 //Utilities::GetFileName(filename));
309 vtkGdcmReader* mReader;
311 //=====================================================================
317 //=====================================================================
318 ImageReader::ImageReader()
321 mLastFilename("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&"),
325 // std::cout << "#### ImageReader::ImageReader()"<<std::endl;
326 if (mUnreadableImage!=0) return;
328 Register(new SpecificVtkReader(vtkPNGReader::New()));
329 Register(new SpecificVtkReader(vtkTIFFReader::New()));
330 Register(new SpecificVtkReader(vtkJPEGReader::New()));
331 Register(new SpecificVtkReader(vtkBMPReader::New()));
332 Register(new SpecificVtkReader(vtkSLCReader::New()));
333 Register(new SpecificVtkReader(vtkMetaImageReader::New(),"MHD",".mhd"));
334 // Register(new SpecificVtkReader(vtkGESignalReader::New()));
335 Register(new DicomReader);
338 std::cout << "## Registered file extensions : "<<std::endl;
339 std::vector<std::string>::const_iterator i;
340 for (i=GetKnownExtensions().begin();
341 i!=GetKnownExtensions().end();
344 std::cout << "'"<<(*i)<<"'"<<std::endl;
348 mUnreadableImage = vtkImageData::New();
350 dim[0] = dim[1] = 32;
352 mUnreadableImage->SetDimensions ( dim );
353 mUnreadableImage->SetScalarTypeToUnsignedChar();
354 mUnreadableImage->AllocateScalars();
355 for (int i=0;i<dim[0];i++)
356 for (int j=0;j<dim[1];j++)
357 mUnreadableImage->SetScalarComponentFromFloat(i,j,0,0,0);
358 for (int i=0;i<dim[0];i++)
360 mUnreadableImage->SetScalarComponentFromFloat(i,i,0,0,255);
361 mUnreadableImage->SetScalarComponentFromFloat(dim[0]-1-i,i,0,0,255);
367 //=====================================================================
369 //=====================================================================
370 ImageReader::~ImageReader()
372 // std::cout << "#### ImageReader::~ImageReader()"<<std::endl;
373 std::vector<SpecificImageReader*>::iterator i;
374 for (i=mReader.begin(); i!=mReader.end(); i++)
376 // std::cout << "#### ImageReader::UnRegister("
377 // << (*i)->GetName()<<")"<<std::endl;
381 if (mUnreadableImage!=0)
383 mUnreadableImage->Delete();
384 mUnreadableImage = 0;
387 //=====================================================================
389 //=====================================================================
390 void ImageReader::Register(SpecificImageReader* r)
392 // std::cout << "#### ImageReader::Register("<<r->GetName()<<")"<<std::endl;
393 mReader.push_back(r);
394 r->PushBackExtensions(mKnownExtensions);
396 //=====================================================================
398 //=====================================================================
399 // Returns true iff the file is readable
400 bool ImageReader::CanRead( const std::string& filename,
401 const std::string& exclude )
403 // std::cout << "## ImageReader::CanRead("<<filename<<")"<<std::endl;
405 std::vector<SpecificImageReader*>::iterator i;
406 for (i=mReader.begin(); i!=mReader.end(); i++)
408 if ((*i)->GetName()==exclude) continue;
409 ok = (*i)->CanRead(filename);
412 mLastFilename = filename;
419 //=====================================================================
421 //=====================================================================
422 // Reads the file (CanRead must be called before : no test here)
423 vtkImageData* ImageReader::Read( const std::string& filename,
424 const std::string& exclude )
426 // std::cout << "## ImageReader::Read("<<filename<<")"<<std::endl;
427 if (mLastFilename!=filename)
429 if (!CanRead(filename,exclude))
431 // std::cout << " -- Cannot read image "<<std::endl;
432 vtkImageData* im = vtkImageData::New();
433 im->ShallowCopy(mUnreadableImage);
437 vtkImageData* i = mLastReader->Read(mLastFilename);
438 // std::cout << "i="<<i<<std::endl;
441 // std::cout << "i=UNREAD"<<i<<std::endl;
442 i = vtkImageData::New();
443 i->ShallowCopy(mUnreadableImage);
445 // std::cout << "i="<<i<<std::endl;
448 //=====================================================================
451 //=====================================================================
452 void ImageReader::ReadDicomInfo(const std::string& filename,
455 // std::cout << "## ImageReader::Read("<<filename<<")"<<std::endl;
456 if (mLastFilename!=filename)
458 if (!CanRead(filename))
463 mLastReader->ReadDicomInfo(mLastFilename,image);
465 //=====================================================================
469 } // namespace creaImageIO