/*========================================================================= Program: GDCM (Grassroots DICOM). A DICOM library Copyright (c) 2006-2011 Mathieu Malaterre All rights reserved. See Copyright.txt or http://gdcm.sourceforge.net/Copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ #include "gdcmReader.h" #include "gdcmDirectory.h" #include "gdcmStringFilter.h" #include #include /* */ static bool process( std::vector & ms, const char * filename) { using namespace gdcm; Tag pd(0x7fe0,0x0000); std::set skiptags; skiptags.insert( pd ); gdcm::Reader reader; reader.SetFileName( filename ); if( !reader.ReadUpToTag( pd, skiptags ) ) { std::cerr << "Failure to read: " << filename << std::endl; return false; } gdcm::File &file = reader.GetFile(); gdcm::DataSet &ds1 = file.GetDataSet(); const gdcm::PrivateTag tseq1(0x5533,0x33,"Visus Change"); if( !ds1.FindDataElement( tseq1 ) ) return true; const gdcm::DataElement& seq1 = ds1.GetDataElement( tseq1 ); SmartPointer sqi1 = seq1.GetValueAsSQ(); const size_t nitems = sqi1->GetNumberOfItems(); for( size_t item = 1; item < nitems; ++item ) { Item &item1 = sqi1->GetItem(item); DataSet &ds2 = item1.GetNestedDataSet(); for(DataSet::ConstIterator it = ds2.Begin(); it != ds2.End(); ++it ) { DataElement const & de = *it; // cannot simply use std::set here, see there is a discrepancy in between // operator== and operator<. // So only use operator== here: std::vector::iterator vit = std::find(ms.begin(), ms.end(), de); if( vit == ms.end() ) ms.push_back(de); } } return true; } int main(int argc, char *argv[]) { bool usefastpath = true; if( argc < 2 ) return 1; using namespace gdcm; const char *filename = argv[1]; gdcm::Directory::FilenamesType filenames; if( !gdcm::System::FileExists(filename) ) { std::cerr << "Could not find file: " << filename << std::endl; return 1; } gdcm::Directory dir; if( gdcm::System::FileIsDirectory(filename) ) { unsigned int nfiles = dir.Load(filename, false); if( nfiles == 0 ) { std::cerr << "Could not find files: " << filename << std::endl; return 1; } filenames = dir.GetFilenames(); } else { filenames.push_back( filename ); } gdcm::StringFilter sf; Tag pd(0x7fe0,0x0000); std::set skiptags; skiptags.insert( pd ); gdcm::Reader reader; reader.SetFileName( filenames[0].c_str() ); if( !reader.ReadUpToTag( pd, skiptags ) ) { std::cerr << "Could not read file: " << filename << std::endl; return 1; } gdcm::File &file = reader.GetFile(); sf.SetFile(file); if( usefastpath ) { // Heuristic, assume if private tag cannot be found in first file, skip the directory gdcm::DataSet &ds1 = file.GetDataSet(); const gdcm::PrivateTag tseq1(0x5533,0x33,"Visus Change"); if( !ds1.FindDataElement( tseq1 ) ){ std::cerr << "Could not find private tag in first file skipping whole directory: " << filename << std::endl; return 0; } } std::vector ms; for(gdcm::Directory::FilenamesType::const_iterator cit = filenames.begin(); cit != filenames.end(); ++cit ) { if( !process(ms, cit->c_str()) ) { return 1; } } if( !ms.empty() ) { std::sort(ms.begin(), ms.end()); std::cout << filename << ",\""; for(std::vector::const_iterator it = ms.begin(); it != ms.end(); ++it ) { DataElement const & de = *it; std::string const & s = sf.ToString( de ); std::cout << de.GetTag() << " " << s << std::endl; } std::cout << "\"" << std::endl; } return 0; }