#include //#include #include #include #include #include #include #include #include //#include #include #include #include "boost/filesystem/path.hpp" namespace creaImageIO { //======================================================================== std::string irclean(const std::string& str) { if (str == "GDCM::Unfound") { return "----"; } if (str[str.size()-1]==' ') { return str.substr(0,str.size()-1); } if (str[str.size()-1]==0) { return str.substr(0,str.size()-1); } return str; } //======================================================================== void IRSplitString ( const std::string& str, const std::string& delimiters, std::vector& tokens) { // Skip delimiters at beginning. std::string::size_type lastPos = str.find_first_not_of(delimiters, 0); // Find first delimiter. std::string::size_type pos = str.find_first_of(delimiters, lastPos); while (std::string::npos != pos || std::string::npos != lastPos) { // Found a token, add it to the vector. // SPECIFIC : REMOVE INITIAL DOT (lastPos + 1) tokens.push_back(str.substr(lastPos+1, pos - lastPos)); // Skip delimiters. Note the "not_of" lastPos = str.find_first_not_of(delimiters, pos); // Find next delimiter pos = str.find_first_of(delimiters, lastPos); } } //===================================================================== // Static members /* std::vector ImageReader::mReader; std::vectorImageReader::mKnownExtensions; vtkImageData* ImageReader::mUnreadableImage = 0; std::string ImageReader::mLastFilename("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&"); SpecificImageReader* ImageReader::mLastReader = 0; //===================================================================== // Global instance : automatic init / destr ImageReader GlobalImageReader; //===================================================================== */ //===================================================================== class SpecificImageReader { public: SpecificImageReader() {} virtual ~SpecificImageReader() {} void SetName(const std::string& s) { mName = s; } const std::string& GetName() const { return mName; } virtual bool CanRead(const std::string& filename) { return false; } virtual vtkImageData* Read(const std::string& filename) { return 0; } virtual void PushBackExtensions(std::vector&) {} virtual void ReadDicomInfo(const std::string& filename, DicomNode* image) {} private: std::string mName; }; //===================================================================== //===================================================================== class SpecificVtkReader : public SpecificImageReader { public: SpecificVtkReader(vtkImageReader2* r, const std::string& name = "", const std::string& extensions = "") : mVTKReader(r), mExtensions(extensions) { if (name.size() == 0) { SetName ( mVTKReader->GetDescriptiveName() ); } else { SetName ( name ); } }; ~SpecificVtkReader() { mVTKReader->Delete(); } bool CanRead(const std::string& filename) { // std::cout << "## Reader "<CanReadFile(filename.c_str())!=0); } vtkImageData* Read(const std::string& filename) { // std::cout << "## Reader "<SetFileName(filename.c_str()); mVTKReader->Update(); im = vtkImageData::New(); im->ShallowCopy(mVTKReader->GetOutput()); } catch (...) { if (im!=0) im->Delete(); im = 0; } return im; } void PushBackExtensions(std::vector& v) { std::string ext = mExtensions; if (ext.size()==0) ext = mVTKReader->GetFileExtensions (); IRSplitString(ext," ",v); } void ReadDicomInfo(const std::string& filename, DicomNode* image) { // std::cout << "SpecificVtkReader::ReadDicomInfo '"<SetFieldValue("A0004_1500",irclean(f)); // Does not work : // How to get the image info without loading it in vtk ? mVTKReader->SetFileName(filename.c_str()); mVTKReader->Update(); //OpenFile(); int ext[6]; mVTKReader->GetDataExtent(ext); // Columns char str[128]; sprintf(str,"%i",ext[1]-ext[0]); // std::cout << "col="<SetFieldValue("A0028_0011",str); // Rows sprintf(str,"%i",ext[3]-ext[2]); // std::cout << "row="<SetFieldValue("A0028_0010",str); // Planes == frames sprintf(str,"%i",ext[5]-ext[4]); // std::cout << "frames="<SetFieldValue("A0028_0008",str); } private: vtkImageReader2* mVTKReader; std::string mExtensions; }; //===================================================================== //===================================================================== void IRFillFields(DicomNode* node, GDCM_NAME_SPACE::File* gdcmFile) { const DicomNodeTypeDescription::FieldDescriptionMapType& dm = node->GetTypeDescription().GetFieldDescriptionMap(); DicomNodeTypeDescription::FieldDescriptionMapType::const_iterator i; DicomNode::FieldValueMapType& vm = node->GetFieldValueMap(); for (i=dm.begin(); i!=dm.end(); ++i) { if ( (i->second.flags==0) && (i->second.group!=0) && (i->second.element!=0) ) { uint16_t gr = i->second.group; uint16_t el = i->second.element; std::string val = gdcmFile->GetEntryString(gr,el); vm[i->first] = irclean(val); } else { vm[i->first] = ""; } } } //===================================================================== //===================================================================== class DicomReader : public SpecificImageReader { public: DicomReader() { mReader = vtkGdcmReader::New(); SetName ( "Dicom" ); }; ~DicomReader() { mReader->Delete(); } bool CanRead(const std::string& filename) { // std::cout << "## Reader "<SetLoadMode( GDCM_NAME_SPACE::LD_ALL); file->SetFileName(filename.c_str()); file->Load(); bool ok = file->IsReadable(); file->Delete(); return ok; } vtkImageData* Read(const std::string& filename) { // std::cout << "## Reader "<SetFileName(filename.c_str()); mReader->Update(); im = vtkImageData::New(); im->ShallowCopy(mReader->GetOutput()); } catch (...) { if (im!=0) im->Delete(); im = 0; } return im; } void PushBackExtensions(std::vector& v) { v.push_back("dcm"); v.push_back(""); } void ReadDicomInfo(const std::string& filename, DicomNode* image) { // std::cout << "DicomReader::ReadDicomInfo '"<SetLoadMode( GDCM_NAME_SPACE::LD_ALL); file->SetFileName(filename.c_str()); file->Load(); if (file->IsReadable()) { DicomNode* cur = image; do { IRFillFields(cur,file); cur = cur->GetParent(); } while (cur); // File name and full file name image->SetFieldValue("FullFileName",filename); boost::filesystem::path full_path(filename); image->SetFieldValue("A0004_1500",full_path.leaf()); //Utilities::GetFileName(filename)); } file->Delete(); } private: vtkGdcmReader* mReader; }; //===================================================================== //===================================================================== ImageReader::ImageReader() : mUnreadableImage(0), mLastFilename("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&"), mLastReader(0) { // std::cout << "#### ImageReader::ImageReader()"<::const_iterator i; for (i=GetKnownExtensions().begin(); i!=GetKnownExtensions().end(); i++) { std::cout << "'"<<(*i)<<"'"<SetDimensions ( dim ); mUnreadableImage->SetScalarTypeToUnsignedChar(); mUnreadableImage->AllocateScalars(); for (int i=0;iSetScalarComponentFromFloat(i,j,0,0,0); for (int i=0;iSetScalarComponentFromFloat(i,i,0,0,255); mUnreadableImage->SetScalarComponentFromFloat(dim[0]-1-i,i,0,0,255); } } //===================================================================== //===================================================================== ImageReader::~ImageReader() { // std::cout << "#### ImageReader::~ImageReader()"<::iterator i; for (i=mReader.begin(); i!=mReader.end(); i++) { // std::cout << "#### ImageReader::UnRegister(" // << (*i)->GetName()<<")"<Delete(); mUnreadableImage = 0; } } //===================================================================== //===================================================================== void ImageReader::Register(SpecificImageReader* r) { // std::cout << "#### ImageReader::Register("<GetName()<<")"<PushBackExtensions(mKnownExtensions); } //===================================================================== //===================================================================== // Returns true iff the file is readable bool ImageReader::CanRead( const std::string& filename, const std::string& exclude ) { // std::cout << "## ImageReader::CanRead("<::iterator i; for (i=mReader.begin(); i!=mReader.end(); i++) { if ((*i)->GetName()==exclude) continue; ok = (*i)->CanRead(filename); if (ok) { mLastFilename = filename; mLastReader = *i; break; } } return ok; } //===================================================================== //===================================================================== // Reads the file (CanRead must be called before : no test here) vtkImageData* ImageReader::Read( const std::string& filename, const std::string& exclude ) { // std::cout << "## ImageReader::Read("<ShallowCopy(mUnreadableImage); return im; } } vtkImageData* i = mLastReader->Read(mLastFilename); // std::cout << "i="<ShallowCopy(mUnreadableImage); } // std::cout << "i="<ReadDicomInfo(mLastFilename,image); } //===================================================================== } // namespace creaImageIO