#include #include #include "boost/filesystem.hpp" #if defined(USE_GDCM) #include #include #include #endif #if defined(USE_GDCM2) #include #endif namespace fs = boost::filesystem; namespace creaImageIO { ///Class used to represent the actual state of the image selected and to perform comparisons on its values class ImageExtent { public: ImageExtent(const std::string& x, const std::string& y, const std::string& z, const std::string& t) { sscanf(x.c_str(),"%d",&mExtent[0]); sscanf(y.c_str(),"%d",&mExtent[1]); sscanf(z.c_str(),"%d",&mExtent[2]); sscanf(t.c_str(),"%d",&mExtent[3]); if(x==""){mExtent[0]=1;} if(y==""){mExtent[1]=1;} if(z==""){mExtent[2]=1;} if(t==""){mExtent[3]=1;} if (mExtent[3]>1) mDim=4; else if (mExtent[2]>1) mDim=3; else if (mExtent[1]>1) mDim=2; else if (mExtent[0]>1) mDim=1; else mDim=0; } ///Clears the extent void Clear() { mExtent[0] = mExtent[1] = mExtent[2] = mExtent[3] = 1; } ///Returns true if the two extents are compatible bool IsCompatible( const ImageExtent& ); ///Adds the extent passed as a parameter to the current extent void Add ( const ImageExtent& ); ///Returns the ieth position of the extent int Get(int i) { return mExtent[i]; } ///Returns the dimension of the current image void SetDimension(int dim) { mDim=dim; } ///Returns the dimension of the current image int GetDimension() { return mDim; } private: int mExtent[4]; int mDim; }; //====================================================================== //====================================================================== // CTor GimmickView::GimmickView(boost::shared_ptr gimmick, int threads) : mGimmick(gimmick), mReader(threads) { GimmickDebugMessage(1,"GimmickView::GimmickView" <GetTreeHandlerMap().begin(); i!= mGimmick->GetTreeHandlerMap().end(); ++i) { this->CreateTreeView(i->second); } } /// Create a tree view with a given name void GimmickView::CreateSingleTreeView(std::string &i_name) { this->CreateTreeView(mGimmick->GetTreeHandlerMap()[i_name]); } //====================================================================== //====================================================================== /// Updates the TreeView of given name from level l to bottom /// (calls the virtual method TreeView::Update()) void GimmickView::UpdateTreeViewLevel(const std::string& t, int l) { TreeViewMapType::iterator i; i = GetTreeViewMap().find(t); if ( i == GetTreeViewMap().end() ) { GimmickError("INTERNAL ERROR : GimmickView::UpdateTreeView : '" <second->UpdateLevel(l); } //====================================================================== /// Clears the status and begins a new selection process void GimmickView::ResetExtent() { if(mImageExtent!=0) { mImageExtent.reset(); } valid=true; } //====================================================================== //====================================================================== bool ImageExtent::IsCompatible(const ImageExtent& ie) { bool compatible=true; ImageExtent * extent= (ImageExtent*)&ie; if((*extent).Get(0)!=Get(0) || (*extent).Get(1)!=Get(1)) { compatible=false; } return compatible; } //====================================================================== //====================================================================== void ImageExtent::Add(const ImageExtent& ie) { ImageExtent * extent= (ImageExtent*)&ie; mExtent[2]+=(*extent).Get(2); if(mExtent[2]>1) { SetDimension(3); } } //====================================================================== /// No selected image bool GimmickView::NoValidateSelected () { GimmickDebugMessage(2,"Validating selected"< ie=boost::shared_ptr(new ImageExtent((*sel).GetAttribute("D0028_0010"), (*sel).GetAttribute("D0028_0011"), (*sel).GetAttribute("D0028_0012"), "")); if(mImageExtent==0) { mImageExtent=ie; if((mImageExtent->Get(min_dim-1)<2)||(mImageExtent->Get(max_dim)>1)) { valid=false; } else { std::stringstream out; out << mImageExtent->GetDimension() << "D image " << mImageExtent->Get(0) << "x"<< mImageExtent->Get(1) << "x"<< mImageExtent->Get(2) <<" selected"; mMessage = out.str(); mImageExtent->SetDimension(2); valid=true; } } else { if(mImageExtent->IsCompatible(*ie)) { if(mImageExtent->GetDimension()==max_dim && mImageExtent->Get(max_dim)>2) { std::stringstream out; out<<"Cannot add this image to selection : would result in a "<GetDimension()+1<<"D image!"; mMessage=out.str(); valid=false; } else if(max_dim<3) { std::stringstream out; out<<"Selecting "<GetDimension()<<"D images is not allowed !"; mMessage=out.str(); valid=false; } else if(min_dim==3 && (ie->Get(2)+mImageExtent->Get(2))<2) { std::stringstream out; out << "Cannot build the selection as it would result in a "; out << mImageExtent->GetDimension(); out << "D image, and the minimum is "; out << min_dim; out << "D!"; mMessage=out.str(); valid=false; } else { mImageExtent->Add(*ie); std::stringstream out; out << mImageExtent->GetDimension() << "D image " << mImageExtent->Get(0) << "x"<< mImageExtent->Get(1) << "x"<< mImageExtent->Get(2) <<" selected"; mMessage = out.str(); } } else { mMessage="The selected images are not compatible."; valid=false; } } } modifyValidationSignal(valid); SetMessage(mMessage); return valid; } //====================================================================== void GimmickView::modifyValidationSignal(bool ivalid) { mValidationSignal(ivalid); } //====================================================================== ///Reads Images (Non Threaded) void GimmickView::ReadImagesNotThreaded(std::vector& s, std::vector im, int dimension) { mReader.Stop(); /* remember! #define GIMMICK_NO_IMAGE_SELECTION 0 #define GIMMICK_2D_IMAGE_SELECTION 2 #define GIMMICK_3D_IMAGE_SELECTION 3 #define GIMMICK_4D_IMAGE_SELECTION 4 #define NATIVE 0 #define _2D 2 #define _3D 3 */ // Create the output data if (im.size()==1) { vtkImageData * out=vtkImageData::New(); out->ShallowCopy(mReader.GetImage(im.front())); s.push_back(out); } else if (im.size()>1) // Test inutile ? JPR { vtkImageData* first = mReader.GetImage( im.front()); if (dimension == 2) { // n3D std::vector::iterator it; for (it=im.begin(); it!=im.end(); ++it) { vtkImageData* out = vtkImageData::New(); out->ShallowCopy(mReader.GetImage(*it)); s.push_back(out); } } else { // n*2D to 3D vtkImageData* out = vtkImageData::New(); // out->CopyStructure(first); out->SetScalarType(first->GetScalarType()); out->SetNumberOfScalarComponents(first->GetNumberOfScalarComponents()); int ext[6]; //first->GetExtent(ext); // JPR first->GetWholeExtent(ext); // renvoie egalement 0,0 en Z // JPR if(ext[5] == 0) { ext[5] = im.size()-1; } else { ext[5] = ext[5] * im.size()-1; // to deal with multiframes - JPR } out->SetExtent(ext); // LG : TODO : Z Spacing ? int dim[3]; first->GetDimensions(dim); out->SetDimensions(dim[0], dim[1], im.size() ); out->AllocateScalars(); out->Update(); unsigned long imsize = dim[0] * dim[1]; imsize = imsize * dim[2] ; // deal with multiframes // JPR //EED 03-11-2009 // differents formats char , short, etc... // differents components 1..3 ex. jpg ->RGB 3 imsize = imsize * first->GetScalarSize() * first->GetNumberOfScalarComponents(); // Order the file name vector double spc[3]; first->GetSpacing(spc); spc[2]=OrderTheFileNameVector(im); out->SetSpacing(spc); int slice = 0; std::vector::iterator it; for (it=im.begin(); it!=im.end(); ++it) { vtkImageData* cur = mReader.GetImage( (*it) ); memcpy(out->GetScalarPointer(0,0,slice), cur->GetScalarPointer(0,0,0), imsize); slice++; } s.push_back(out); } // dimension == 3 } // size >1 } //====================================================================== #if defined(USE_GDCM) double GimmickView::OrderTheFileNameVector(std::vector &im) { double spacing=1; typedef std::vector FileList; FileList fileVector; //GDCM_NAME_SPACE::File *f = GDCM_NAME_SPACE::File::New(); GDCM_NAME_SPACE::SerieHelper *sh = GDCM_NAME_SPACE::SerieHelper::New(); std::vector lstAux; std::vector::iterator it; for (it=im.begin(); it!=im.end(); ++it) { ///\TODO liberer les GDCM_NAME_SPACE::File a la fin! // JPR GDCM_NAME_SPACE::File *f = GDCM_NAME_SPACE::File::New(); f->SetFileName(*it); f->Load(); if (f->IsReadable()) { fileVector.push_back(f); } else { lstAux.push_back(*it); } } // for if ((fileVector.size()>1) && (sh->IsCoherent( &fileVector ))) { sh->OrderFileList(&fileVector); spacing= sh->GetZSpacing(); im.clear(); int i; for (i=0; iGetFileName() ); } for (i=0; i &im) { return 1; } #endif //====================================================================== void GimmickView::ReadImagesNotThreadedInVector(std::vector& s, std::vector im, int dimension) { // Create the output data if (im.size()==1) { // Only one image : give it vtkImageData* out = vtkImageData::New(); GimmickDebugMessage(3, "State Check: Full Filename: " <ShallowCopy(mReader.GetImage(im.front())); s.push_back( out ); } else if (im.size()>1) // Test inutile ? JPR { vtkImageData* first = mReader.GetImage( im.front()); if (dimension == 2) { // n3D std::vector::iterator it; for (it=im.begin(); it!=im.end(); ++it) { vtkImageData* out = vtkImageData::New(); out->ShallowCopy(mReader.GetImage(*it)); s.push_back(out); } } else { // n2D to 3D // NO! // n *2D + T in a vector : std::vector::iterator it; for (it=im.begin(); it!=im.end(); ++it) { vtkImageData* out = mReader.GetImage( (*it)); s.push_back(out); } } } } //====================================================================== //====================================================================== ///Requests the reading of an image void GimmickView::RequestReading(tree::Node* n, int prio, int selection_index, boost::shared_ptr p) { if(!mReaderStarted) { mReader.Start(); mReaderStarted=true; } ImageEventType t(n,selection_index); t.pointerHolder = p; mImageEventMap[n->GetAttribute("FullFileName")] = t; mReader.Request(this,n->GetAttribute("FullFileName"),prio); } //====================================================================== //====================================================================== void GimmickView:: OnMultiThreadImageReaderEvent(const std::string& filename, MultiThreadImageReaderUser::EventType e, vtkImageData* image) { GimmickDebugMessage(7, "MultiThreadImageReader event : "< 0 if(mImageEventMap.size()>0){ i = mImageEventMap.find(filename); if (i!=mImageEventMap.end()) { GimmickDebugMessage(5, "Putting image of file '"<second); ie.image = image; ie.pointerHolder->Set(ie.image); //mImageEventMap.erase(i); } } } else if (e==Error) { std::string mess="ERROR: MultiThreadImageReader: Cannot read image in file "; mess+=filename; mess+="\n"; GimmickMessage(1,mess); ImageEventTypeMap::iterator i; i = mImageEventMap.find(filename); if (i!=mImageEventMap.end()) { ImageEventType ie(i->second); ie.image = image; ie.pointerHolder->Set(GetDefaultImage()); //mImageEventMap.erase(i); } } else if (e==ImageUnloaded) { std::string mess="Unloaded image in file "; mess+=filename; mess+="\n"; GimmickMessage(1,mess); ImageEventTypeMap::iterator i; i = mImageEventMap.find(filename); if (i!=mImageEventMap.end()) { ImageEventType ie(i->second); ie.image = image; ie.pointerHolder->Set(GetDefaultImage()); //mImageEventMap.erase(i); } } } //==================================================================== //==================================================================== void GimmickView::ConnectValidationObserver(ValidationCallbackType callback) { mValidationSignal.connect(callback); } } // EO namespace creaImageIO ////////////////////////////////////////////////////////////////////// //void GimmickView::Anonymize(std::vector i_filenames, int type) // { //if(type == 0) //{ // // Get private key/certificate // gdcm::CryptographicMessageSyntax cms; //if( !dumb_mode ) // { // if( !GetRSAKeys(cms, rsa_path.c_str(), cert_path.c_str() ) ) // { // return 1; // } // cms.SetCipherType( ciphertype ); // } //// Setup gdcm::Anonymizer //gdcm::Anonymizer anon; //if( !dumb_mode ) // anon.SetCryptographicMessageSyntax( &cms ); //if( dumb_mode ) // { // for(unsigned int i = 0; i < nfiles; ++i) // { // const char *in = filenames[i].c_str(); // const char *out = outfilenames[i].c_str(); // if( !AnonymizeOneFileDumb(anon, in, out, empty_tags, remove_tags, replace_tags_value) ) // { // //std::cerr << "Could not anonymize: " << in << std::endl; // return 1; // } // } // } //else // { // for(unsigned int i = 0; i < nfiles; ++i) // { // const char *in = filenames[i].c_str(); // const char *out = outfilenames[i].c_str(); // if( !AnonymizeOneFile(anon, in, out) ) // { // //std::cerr << "Could not anonymize: " << in << std::endl; // return 1; // } // } // } // }