fw4spl
fwGdcmIO/src/fwGdcmIO/helper/DicomSearch.cpp
1 /* ***** BEGIN LICENSE BLOCK *****
2  * FW4SPL - Copyright (C) IRCAD, 2009-2017.
3  * Distributed under the terms of the GNU Lesser General Public License (LGPL) as
4  * published by the Free Software Foundation.
5  * ****** END LICENSE BLOCK ****** */
6 
7 #include "fwGdcmIO/helper/DicomSearch.hpp"
8 
9 #include <fwCore/base.hpp>
10 
11 #include <fwJobs/Observer.hpp>
12 
13 #include <boost/assign/list_of.hpp>
14 
15 namespace fwGdcmIO
16 {
17 namespace helper
18 {
19 
20 //------------------------------------------------------------------------------
21 
22 bool isDICOM(const ::boost::filesystem::path& filepath)
23 {
24  ::boost::filesystem::ifstream ifs( filepath, std::ios::binary );
25  ifs.seekg(128);
26  char DICM[5] = {0};
27  ifs.read(DICM, 4);
28  ifs.close();
29  return strcmp(DICM, "DICM") == 0;
30 }
31 
32 //------------------------------------------------------------------------------
33 
34 void DicomSearch::searchRecursively(const ::boost::filesystem::path& dirPath,
35  std::vector< ::boost::filesystem::path >& dicomFiles,
36  bool checkIsDicom,
37  const ::fwJobs::Observer::sptr& readerObserver)
38 {
39  std::vector< ::boost::filesystem::path > fileVect;
40  checkFilenameExtension(dirPath, fileVect, readerObserver);
41 
42  if(checkIsDicom)
43  {
44  if(readerObserver)
45  {
46  readerObserver->setTotalWorkUnits(fileVect.size());
47  }
48 
49  std::uint64_t progress = 0;
50  for(auto file : fileVect)
51  {
52  if(readerObserver)
53  {
54  readerObserver->doneWork(++progress);
55 
56  if(readerObserver->cancelRequested())
57  {
58  dicomFiles.clear();
59  break;
60  }
61  }
62 
63  bool isDicom = isDICOM(file);
64  if(isDicom)
65  {
66  dicomFiles.push_back( file );
67  }
68  SLM_WARN_IF("Failed to read: " + file.string(), !isDicom);
69  }
70  }
71  else
72  {
73  dicomFiles = fileVect;
74  }
75 }
76 
77 //------------------------------------------------------------------------------
78 
79 void DicomSearch::checkFilenameExtension(const ::boost::filesystem::path& dirPath,
80  std::vector< ::boost::filesystem::path >& dicomFiles,
81  const ::fwJobs::Observer::sptr& fileLookupObserver)
82 {
83  dicomFiles.clear();
84 
85  std::set<std::string> extensions = ::boost::assign::list_of(".jpg")(".jpeg")(".htm")(".html")(".txt")(".xml")
86  (".stm")(".str")(".lst")(".ifo")(".pdf")(".gif")
87  (".png")(".exe")(".zip")(".gz")(".dir")(".dll")(".inf")
88  (".DS_Store");
89 
90  for(::boost::filesystem::recursive_directory_iterator it(dirPath);
91  it != ::boost::filesystem::recursive_directory_iterator(); ++it)
92  {
93  if(fileLookupObserver && fileLookupObserver->cancelRequested())
94  {
95  dicomFiles.clear();
96  break;
97  }
98 
99  if(!::boost::filesystem::is_directory(*it))
100  {
101  auto path = it->path();
102  std::string ext = path.extension().string();
103  std::transform(ext.begin(), ext.end(), ext.begin(), tolower);
104 
105  if(extensions.find(ext) == extensions.end())
106  {
107  std::string stem = path.stem().string();
108  std::transform(stem.begin(), stem.end(), stem.begin(), tolower);
109 
110  if(stem != "dicomdir")
111  {
112  dicomFiles.push_back(path.string());
113  }
114  }
115  }
116  }
117 }
118 
119 //------------------------------------------------------------------------------
120 
121 } //namespace helper
122 } //namespace fwGdcmIO
123 
The namespace fwGdcmIO contains reader, writer and helper for dicom data.
static void checkFilenameExtension(const ::boost::filesystem::path &dirPath, std::vector< ::boost::filesystem::path > &dicomFiles, const std::shared_ptr< ::fwJobs::Observer > &fileLookupObserver=nullptr)
retrieve files according to extension.
static FWGDCMIO_API void searchRecursively(const ::boost::filesystem::path &dirPath, std::vector< ::boost::filesystem::path > &dicomFiles, bool checkIsDicom, const std::shared_ptr< ::fwJobs::Observer > &fileLookupObserver=nullptr)
Search Dicom files recursively by excluding files with known extensions.
#define SLM_WARN_IF(message, cond)
Definition: spyLog.hpp:265