/* # --------------------------------------------------------------------- # # Copyright (c) CREATIS (Centre de Recherche en Acquisition et Traitement de l'Image # pour la Santé) # Authors : Eduardo Davila, Frederic Cervenansky, Claire Mouton # Previous Authors : Laurent Guigues, Jean-Pierre Roux # CreaTools website : www.creatis.insa-lyon.fr/site/fr/creatools_accueil # # This software is governed by the CeCILL-B license under French law and # abiding by the rules of distribution of free software. You can use, # modify and/ or redistribute the software under the terms of the CeCILL-B # license as circulated by CEA, CNRS and INRIA at the following URL # http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html # or in the file LICENSE.txt. # # As a counterpart to the access to the source code and rights to copy, # modify and redistribute granted by the license, users are provided only # with a limited warranty and the software's author, the holder of the # economic rights, and the successive licensors have only limited # liability. # # The fact that you are presently reading this means that you have had # knowledge of the CeCILL-B license and that you accept its terms. # ------------------------------------------------------------------------ */ #include #include "boost/filesystem.hpp" #if defined(USE_GDCM) #include #include #include #include #include #endif /*#if defined(USE_GDCM2) #include #include "gdcmSystem.h" #include "gdcmCryptographicMessageSyntax.h" #include "gdcmUIDGenerator.h" #include "gdcmAnonymizer.h" #include "gdcmGlobal.h" #endif*/ #if defined(_WIN32) #pragma warning(disable: 4996) #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); } void GimmickView::stopReader() { mReader.Stop(); } //====================================================================== ///Reads Images (Non Threaded) void GimmickView::ReadImagesNotThreaded(std::vector& s, std::vector im, int dimension) { stopReader(); /* 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] = (int)im.size()-1; } else { ext[5] = ext[5] * (int)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], (int)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); // OrderTheFileNameVector is not here anymore. // Try orderFilesWithZSpacing from OutputModel FCY // spc[2]=OrderTheFileNameVector(im); spc[2] =1; 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 } //====================================================================== ////////////////////////////////////////////////////////// // Test if the image is a multiple or single frame. // For the moment only with the creation of vtkImageDta. // TO DO with image size and dim!!! ////////////////////////////////////////////////////////// bool GimmickView::isSingle(const std::string i_file) { bool bres = true; vtkImageData* first = mReader.GetImage( i_file); int dim[3]; first->GetDimensions(dim); if (dim[2] > 1) { bres = false; } else { } return bres; } ////////////////////////////////////////////////////////// // get Attributes values for a file ////////////////////////////////////////////////////////// void GimmickView::getAttributes(const std::string i_file, std::map &o_infos, OutputAttr i_attr) { if(i_attr.inside.size() >0) { mGimmick->GetAttributes(i_file,o_infos,i_attr); } if(i_attr.outside.size()>0) { mReader.getAttributes(i_file,o_infos, i_attr.outside); } } ////////////////////////////////////////////////////////// // create an output structure with n entries = n output ////////////////////////////////////////////////////////// void GimmickView::readImages1(std::vector& o_output, std::vector im, OutputAttr i_attr) { i_attr.outside.push_back("D0019_100a"); // simens Number Of Images In Mosaic std::vector::iterator it; for (it=im.begin(); it!=im.end(); ++it) { OutStrGimmick out; out.img = vtkImageData::New(); out.img->ShallowCopy(mReader.GetImage(*it)); if(i_attr.mult) { getAttributes((*it),out.infos,i_attr); } o_output.push_back(out); } // If we want only one output information structure, we set it outside the loop if(!i_attr.mult) { getAttributes(im.front(), o_output.front().infos, i_attr); } } ////////////////////////////////////////////////////////// // create an output structure with n entries = 1 output ////////////////////////////////////////////////////////// void GimmickView::readImages3(std::vector& o_output, std::vector im, OutputAttr i_attr, double i_zspc) { OutStrGimmick out; vtkImageData* first = mReader.GetImage( im.front()); out.img = vtkImageData::New(); out.img->SetScalarType(first->GetScalarType()); out.img->SetNumberOfScalarComponents(first->GetNumberOfScalarComponents()); int ext[6]; first->GetWholeExtent(ext); // send also 0,0 in Z if(ext[5] == 0) { ext[5] = (int)im.size()-1; } else { ext[5] = ext[5] * (int)im.size()-1; // to deal with multiframes } out.img->SetExtent(ext); int dim[3]; double spac[3]; first->GetDimensions(dim); first->GetSpacing(spac); out.img->SetSpacing(spac); out.img->SetDimensions(dim[0], dim[1], (int)im.size() ); out.img->AllocateScalars(); out.img->Update(); unsigned long imsize = dim[0] * dim[1]; imsize = imsize * dim[2] ; // deal with multiframes here // differents formats char , short, etc... // differents components 1..3 ex. jpg ->RGB 3 imsize = imsize * first->GetScalarSize() * first->GetNumberOfScalarComponents(); // Order the file name vector already did with the OutputModel!!! //!!!!out.img->SetSpacing(i_zspc); int slice = 0; std::vector::iterator it; for (it=im.begin(); it!=im.end(); ++it) { vtkImageData* cur = mReader.GetImage( (*it) ); memcpy(out.img->GetScalarPointer(0,0,slice), cur->GetScalarPointer(0,0,0), imsize); slice++; } getAttributes(im.front(),out.infos, i_attr); o_output.push_back(out); } // TO DO NO VERY SURE : NEED TO BE TESTED ////////////////////////////////////////////////////////// // create an output structure with n entries (T size) = T output (n size) ////////////////////////////////////////////////////////// void GimmickView::readImages2(std::vector& o_output, std::vector im, OutputAttr i_attr, double i_zspc) { vtkImageData* first = mReader.GetImage( im.front()); int dim[3]; double spac[3]; first->GetDimensions(dim); first->GetSpacing(spac); // differents formats char , short, etc... // differents components 1..3 ex. jpg ->RGB 3 unsigned long imsize = dim[0] * dim[1]; imsize = imsize * first->GetScalarSize() * first->GetNumberOfScalarComponents(); // Order the file name vector already did with the OutputModel!!! std::vector::iterator it; std::vector::iterator it_out = o_output.begin(); for (it=im.begin(); it!=im.end(); ++it)//, it_out ++) { vtkImageData* cur = mReader.GetImage( (*it) ); for (int slice= 0 ; slice SetScalarType(first->GetScalarType()); out.img->SetSpacing(spac); out.img->SetNumberOfScalarComponents(first->GetNumberOfScalarComponents()); int ext[6]; first->GetWholeExtent(ext); // send also 0,0 in Z ext[5] = 0; out.img->SetExtent(ext); out.img->SetDimensions(dim[0], dim[1], 1 ); out.img->AllocateScalars(); out.img->Update(); memcpy(out.img->GetScalarPointer(0,0,0), cur->GetScalarPointer(0,0,slice), imsize); o_output.push_back(out); } // if(i_attr.mult) // getAttributes((*it),(*it_out).infos,i_attr); } if(!i_attr.mult) { getAttributes(im.front(), o_output.front().infos,i_attr); } } ////////////////////////////////////////////////////////// // create an output structure with n entries (T size) = T + n output ////////////////////////////////////////////////////////// void GimmickView::readImages4(std::vector& o_output, std::vector im, OutputAttr i_attr) { std::vector::iterator it; std::vector::iterator it_out = o_output.begin(); vtkImageData* first = mReader.GetImage( im.front()); int dim[3]; first->GetDimensions(dim); for (int slice= 0 ; slice SetScalarType(first->GetScalarType()); out.img->SetNumberOfScalarComponents(first->GetNumberOfScalarComponents()); int ext[6]; double spac[6]; first->GetWholeExtent(ext); // send also 0,0 in Z ext[5] = 0; out.img->SetExtent(ext); first->GetSpacing(spac); out.img->SetSpacing(spac); out.img->SetDimensions(dim[0], dim[1], (int)im.size() ); out.img->AllocateScalars(); out.img->Update(); unsigned long imsize = dim[0] * dim[1]; imsize = imsize * first->GetScalarSize() * first->GetNumberOfScalarComponents(); int index = 0; for (it=im.begin(); it!=im.end(); ++it, index ++) { vtkImageData* cur = mReader.GetImage( (*it) ); memcpy(out.img->GetScalarPointer(0,0,index), cur->GetScalarPointer(0,0,slice), imsize); o_output.push_back(out); } } if(!i_attr.mult) // No sense to take informations in all images { getAttributes(im.front(), o_output.front().infos,i_attr); } } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Global function to read Images and create wished output (informations, multiple, type and size of output...) // In function of type (file, vector) and size, the correct readImages function is selected ////////////////////////////////////////////////////////////////////////////////////////////////////////////// void GimmickView::readImages(std::vector& o_output, std::vector im, OutputAttr i_attr, int i_dim, double i_zspc) { int size = (int)im.size(); if ( size == 0) { return; } else if (size == 1) { // Simplest case // Only one image : give it // But take in count multiframe possibility if ( isSingle(im.front()) || i_dim != 1) { readImages1(o_output,im, i_attr); } else { readImages2(o_output,im, i_attr,i_zspc); } } else { // multiple or single frame if ( isSingle(im.front()) ) { //we deal with 2D images if(i_dim == 1) { // 2D to 3D readImages3(o_output,im, i_attr,i_zspc); } else { readImages1(o_output,im, i_attr); } } else { // we deal with multiple frames n x (2D x T) // Differents outputs are avaialable if(i_dim == 1) { // put all in one output readImages3(o_output,im, i_attr,i_zspc); } else if( i_dim == 2) { // put in a vector of n x T (2D) readImages2(o_output,im, i_attr,i_zspc); } else if( i_dim == 3) { // put in a vector of n (2D x T) // No transformations. readImages1(o_output,im, i_attr); } else { // put in a vector of T (2D x n) readImages4(o_output,im, i_attr); } // i_dim } //isSingle(im.front()) } // if size //EED UnMosaic step... //How to verifie if is a mosaic file , with how many images inside?? } 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 { /// \TODO fix unused variable 'first' // 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); } // for } 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); } // for } // if dimension } // if im.size } //====================================================================== //====================================================================== ///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); } #if defined(USE_GDCM) //////////////////////////////////////////////////////////////////////// void GimmickView::Anonymize(std::vector i_filenames, int type) { bool res = true; std::vector filesH; std::vector suid; std::map msuid; std::string tempuid = GDCM_NAME_SPACE::Util::CreateUniqueUID(); int i = 1; std::vector::iterator it = i_filenames.begin(); for(; it != i_filenames.end(); it++) { GDCM_NAME_SPACE::File *file; file = GDCM_NAME_SPACE::File::New( ); file->SetLoadMode( GDCM_NAME_SPACE::LD_ALL ); file->SetFileName( (*it).c_str() ); res = file->Load(); if ( !res ) { std::cerr << "Sorry, " << (*it).c_str() <<" not a gdcm-readable " << "DICOM / ACR File" <Delete(); //return 0; } std::cout << " ... is readable " << std::endl; // We need a gdcm::FileHelper, since we want to load the pixels GDCM_NAME_SPACE::FileHelper *fh = GDCM_NAME_SPACE::FileHelper::New(file); //Borrame //EED uint8_t *imageData = fh->GetImageData(); // Institution name file->AddAnonymizeElement(0x0008, 0x0080, "*"); // Patient's name file->AddAnonymizeElement(0x0010, 0x0010, "*"); // Patient's ID file->AddAnonymizeElement( 0x0010, 0x0020,"1515" ); // Study Instance UID file->AddAnonymizeElement(0x0020, 0x000d, tempuid ); // Telephone file->AddAnonymizeElement(0x0010, 0x2154, "3615" ); // Aware user will add here more fields to anonymize here // The gdcm::File is modified in memory file->AnonymizeFile(); i++; fh->SetContentType(GDCM_NAME_SPACE::UNMODIFIED_PIXELS_IMAGE); fh->WriteDcmExplVR(file->GetFileName() +".ano1" ); std::cout << i <<" End Anonymize" << std::endl; file->ClearAnonymizeList(); file->Delete(); fh->Delete(); } } #endif #if defined(USE_GDCM2) void GimmickView::Anonymize(std::vector i_filenames, int type) { } #endif //////////////////////////////////////////////////////////////////////// //void GimmickView::Anonymize(std::vector i_filenames, int type) //{ // // gdcm::FileMetaInformation::SetSourceApplicationEntityTitle( "gdcmanon" ); // gdcm::Global& g = gdcm::Global::GetInstance(); // //if( !resourcespath ) // // { // // const char *xmlpathenv = getenv("GDCM_RESOURCES_PATH"); // // if( xmlpathenv ) // // { // // // Make sure to look for XML dict in user explicitly specified dir first: // // xmlpath = xmlpathenv; // // resourcespath = 1; // // } // // } // // if( resourcespath ) // // { // // // xmlpath is set either by the cmd line option or the env var // // if( !g.Prepend( xmlpath.c_str() ) ) // // { // // std::cerr << "Specified Resources Path is not valid: " << xmlpath << std::endl; // // return 1; // // } // // } // // All set, then load the XML files: // if( !g.LoadResourcesFiles() ) // { // return ; // } // const gdcm::Defs &defs = g.GetDefs(); (void)defs; // if( !rootuid ) // { // // only read the env var if no explicit cmd line option // // maybe there is an env var defined... let's check // const char *rootuid_env = getenv("GDCM_ROOT_UID"); // if( rootuid_env ) // { // rootuid = 1; // root = rootuid_env; // } // } // if( rootuid ) // { // // root is set either by the cmd line option or the env var // if( !gdcm::UIDGenerator::IsValid( root.c_str() ) ) // { // std::cerr << "specified Root UID is not valid: " << root << std::endl; // return 1; // } // gdcm::UIDGenerator::SetRoot( root.c_str() ); // } // // 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; // // } // // } // // } // } //} // } // EO namespace creaImageIO