fw4spl
TagValueInstanceRemoveSplitter.cpp
1 /* ***** BEGIN LICENSE BLOCK *****
2  * FW4SPL - Copyright (C) IRCAD, 2009-2018.
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 "fwDicomIOFilter/splitter/TagValueInstanceRemoveSplitter.hpp"
8 
9 #include "fwDicomIOFilter/exceptions/FilterFailure.hpp"
10 #include "fwDicomIOFilter/registry/macros.hpp"
11 
12 #include <dcmtk/config/osconfig.h>
13 #include <dcmtk/dcmdata/dcdeftag.h>
14 #include <dcmtk/dcmdata/dcfilefo.h>
15 #include <dcmtk/dcmdata/dcistrmb.h>
16 #include <dcmtk/dcmimgle/dcmimage.h>
17 #include <dcmtk/dcmnet/diutil.h>
18 
19 fwDicomIOFilterRegisterMacro( ::fwDicomIOFilter::splitter::TagValueInstanceRemoveSplitter );
20 
21 namespace fwDicomIOFilter
22 {
23 namespace splitter
24 {
25 
26 const std::string TagValueInstanceRemoveSplitter::s_FILTER_NAME = "Tag value instance remove splitter";
28  "Remove instances according to a tag value.";
29 
30 //-----------------------------------------------------------------------------
31 
33  ISplitter()
34 {
35  m_tag = DCM_UndefinedTagKey;
36  m_tagValue = "";
37 }
38 
39 //-----------------------------------------------------------------------------
40 
42 {
43 }
44 
45 //-----------------------------------------------------------------------------
46 
48 {
50 }
51 
52 //-----------------------------------------------------------------------------
53 
55 {
57 }
58 
59 //-----------------------------------------------------------------------------
60 
62 {
63  return true;
64 }
65 
66 //-----------------------------------------------------------------------------
67 
68 TagValueInstanceRemoveSplitter::DicomSeriesContainerType TagValueInstanceRemoveSplitter::apply(
69  const ::fwMedData::DicomSeries::sptr& series, const ::fwLog::Logger::sptr& logger)
70 const
71 {
72  if(m_tag == DCM_UndefinedTagKey)
73  {
74  const std::string msg = "Unable to split the series, the specified tag is not valid.";
75  throw ::fwDicomIOFilter::exceptions::FilterFailure(msg);
76  }
77 
78  DicomSeriesContainerType result;
79 
80  typedef std::vector< ::fwMemory::BufferObject::sptr > InstanceContainerType;
81 
82  // Create a container to store the instances
83  InstanceContainerType instances;
84 
85  OFCondition status;
86  DcmDataset* dataset;
87  OFString data;
88 
89  for(const auto& item : series->getDicomContainer())
90  {
91  const ::fwMemory::BufferObject::sptr bufferObj = item.second;
92  const size_t buffSize = bufferObj->getSize();
93  ::fwMemory::BufferObject::Lock lock(bufferObj);
94  char* buffer = static_cast< char* >( lock.getBuffer() );
95 
96  DcmInputBufferStream is;
97  is.setBuffer(buffer, offile_off_t(buffSize));
98  is.setEos();
99 
100  DcmFileFormat fileFormat;
101  fileFormat.transferInit();
102  if (!fileFormat.read(is).good())
103  {
104  FW_RAISE("Unable to read Dicom file '"<< bufferObj->getStreamInfo().fsFile.string() <<"' "<<
105  "(slice: '" << item.first << "')");
106  }
107 
108  fileFormat.loadAllDataIntoMemory();
109  fileFormat.transferEnd();
110 
111  dataset = fileFormat.getDataset();
112 
113  // Get the value of the instance
114  dataset->findAndGetOFStringArray(m_tag, data);
115  const std::string value = data.c_str();
116 
117  if(value != m_tagValue)
118  {
119  instances.push_back(bufferObj);
120  }
121  else
122  {
123  logger->warning("An instance has been removed from the series.");
124  }
125  }
126 
127  // Update series
128  series->clearDicomContainer();
129  size_t index = 0;
130  for(const auto& buffer : instances)
131  {
132  series->addBinary(index++, buffer);
133  }
134  series->setNumberOfInstances(series->getDicomContainer().size());
135  result.push_back(series);
136 
137  return result;
138 }
139 
140 } // namespace splitter
141 } // namespace fwDicomIOFilter
virtual FWDICOMIOFILTER_API ~TagValueInstanceRemoveSplitter()
Destructor.
virtual FWDICOMIOFILTER_API std::string getName() const override
Return the name of the filter.
Filter that remove instances according to tag value.
fwDicomIOFilter contains filters used to pre-process images before reading.
base class for BufferObject Lock
LockBase< T >::BufferType getBuffer() const
Returns BufferObject&#39;s buffer pointer.
virtual FWDICOMIOFILTER_API bool isConfigurationRequired() const override
Return true if a configuration is required.
Key class used to restrict access to Filter construction. See http://www.drdobbs.com/184402053.
FWDICOMIOFILTER_API TagValueInstanceRemoveSplitter(::fwDicomIOFilter::IFilter::Key key)
Constructor.
virtual FWDICOMIOFILTER_API std::string getDescription() const override
Return the description of the filter.
virtual FWDICOMIOFILTER_API DicomSeriesContainerType apply(const ::fwMedData::DicomSeries::sptr &series, const ::fwLog::Logger::sptr &logger) const override
Override.
Base class for Dicom instance splitter.
Definition: ISplitter.hpp:23
std::string m_tagValue
Tag value used to determine if an instance must be removed.