fw4spl
TagValueSorter.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/sorter/TagValueSorter.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::sorter::TagValueSorter );
20 
21 namespace fwDicomIOFilter
22 {
23 namespace sorter
24 {
25 
26 const std::string TagValueSorter::s_FILTER_NAME = "Tag value sorter";
27 const std::string TagValueSorter::s_FILTER_DESCRIPTION =
28  "Sort instances using a tag value.";
29 
30 //-----------------------------------------------------------------------------
31 
33  ISorter()
34 {
35  m_tag = DCM_UndefinedTagKey;
36 }
37 
38 //-----------------------------------------------------------------------------
39 
41 {
42 }
43 
44 //-----------------------------------------------------------------------------
45 
46 std::string TagValueSorter::getName() const
47 {
49 }
50 
51 //-----------------------------------------------------------------------------
52 
53 std::string TagValueSorter::getDescription() const
54 {
56 }
57 
58 //-----------------------------------------------------------------------------
59 
61 {
62  return true;
63 }
64 
65 //-----------------------------------------------------------------------------
66 
67 TagValueSorter::DicomSeriesContainerType TagValueSorter::apply(
68  const ::fwMedData::DicomSeries::sptr& series, const ::fwLog::Logger::sptr& logger)
69 const
70 {
71  if(m_tag == DCM_UndefinedTagKey)
72  {
73  const std::string msg = "Unable to split the series, the specified tag is not valid.";
74  throw ::fwDicomIOFilter::exceptions::FilterFailure(msg);
75  }
76 
77  DicomSeriesContainerType result;
78 
79  ::fwMedData::DicomSeries::DicomContainerType sortedDicom;
80 
81  OFCondition status;
82  DcmDataset* dataset;
83  for(const auto& item : series->getDicomContainer())
84  {
85  const ::fwMemory::BufferObject::sptr bufferObj = item.second;
86  const size_t buffSize = bufferObj->getSize();
87  ::fwMemory::BufferObject::Lock lock(bufferObj);
88  char* buffer = static_cast< char* >( lock.getBuffer() );
89 
90  DcmInputBufferStream is;
91  is.setBuffer(buffer, offile_off_t(buffSize));
92  is.setEos();
93 
94  DcmFileFormat fileFormat;
95  fileFormat.transferInit();
96  if (!fileFormat.read(is).good())
97  {
98  FW_RAISE("Unable to read Dicom file '"<< bufferObj->getStreamInfo().fsFile.string() <<"' "<<
99  "(slice: '" << item.first << "')");
100  }
101 
102  fileFormat.loadAllDataIntoMemory();
103  fileFormat.transferEnd();
104 
105  dataset = fileFormat.getDataset();
106 
107  Sint32 index = 0;
108  dataset->findAndGetSint32(m_tag, index);
109 
110  sortedDicom[size_t(index)] = bufferObj;
111  }
112 
113  if(sortedDicom.size() != series->getDicomContainer().size())
114  {
115  const std::string msg = "Unable to sort the series using the specified tag. The tag may be missing in "
116  "some instances or several instances may have the same tag value.";
117  throw ::fwDicomIOFilter::exceptions::FilterFailure(msg);
118  }
119 
120  series->clearDicomContainer();
121  for(const auto& item : sortedDicom)
122  {
123  series->addBinary(item.first, item.second);
124  }
125 
126  result.push_back(series);
127 
128  std::stringstream ss;
129  ss << "The instances have been sorted using the value of tag (" <<
130  std::hex << std::setfill('0') << std::setw(4) << m_tag.getGroup() << "," <<
131  std::hex << std::setfill('0') << std::setw(4) << m_tag.getElement() << ").";
132  logger->information(ss.str());
133 
134  return result;
135 }
136 
137 } // namespace sorter
138 } // namespace fwDicomIOFilter
virtual FWDICOMIOFILTER_API bool isConfigurationRequired() const override
Return true if a configuration is required.
fwDicomIOFilter contains filters used to pre-process images before reading.
base class for BufferObject Lock
virtual FWDICOMIOFILTER_API ~TagValueSorter()
Destructor.
Filter that uses a tag to sort the instances.
virtual FWDICOMIOFILTER_API std::string getDescription() const override
Return the description of the filter.
static const std::string s_FILTER_DESCRIPTION
Filter description.
FWDICOMIOFILTER_API TagValueSorter(::fwDicomIOFilter::IFilter::Key key)
Constructor.
virtual FWDICOMIOFILTER_API std::string getName() const override
Return the name of the filter.
LockBase< T >::BufferType getBuffer() const
Returns BufferObject&#39;s buffer pointer.
Key class used to restrict access to Filter construction. See http://www.drdobbs.com/184402053.
virtual FWDICOMIOFILTER_API DicomSeriesContainerType apply(const ::fwMedData::DicomSeries::sptr &series, const ::fwLog::Logger::sptr &logger) const override
Override.
static const std::string s_FILTER_NAME
Filter name.
DcmTagKey m_tag
Tag used to sort instances.
Base class for Dicom instance sorter.
Definition: ISorter.hpp:23