fw4spl
SOPClassUIDSplitter.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/SOPClassUIDSplitter.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/dcmdata/dcuid.h>
17 #include <dcmtk/dcmimgle/dcmimage.h>
18 #include <dcmtk/dcmnet/diutil.h>
19 
20 fwDicomIOFilterRegisterMacro( ::fwDicomIOFilter::splitter::SOPClassUIDSplitter );
21 
22 namespace fwDicomIOFilter
23 {
24 namespace splitter
25 {
26 
27 const std::string SOPClassUIDSplitter::s_FILTER_NAME = "SOPClassUID splitter";
29  "Split instances according to <i>SOPClassUID</i> tag.";
30 
31 //-----------------------------------------------------------------------------
32 
34  ::fwDicomIOFilter::splitter::TagValueSplitter(key)
35 {
36  this->setTag(DCM_SOPClassUID);
37 }
38 
39 //-----------------------------------------------------------------------------
40 
42 {
43 }
44 
45 //-----------------------------------------------------------------------------
46 
47 std::string SOPClassUIDSplitter::getName() const
48 {
50 }
51 
52 //-----------------------------------------------------------------------------
53 
55 {
57 }
58 
59 //-----------------------------------------------------------------------------
60 
62 {
63  return false;
64 }
65 
66 //-----------------------------------------------------------------------------
67 
68 SOPClassUIDSplitter::DicomSeriesContainerType SOPClassUIDSplitter::apply(
69  const ::fwMedData::DicomSeries::sptr& series,
70  const ::fwLog::Logger::sptr& logger) const
71 {
72  const DicomSeriesContainerType result = ::fwDicomIOFilter::splitter::TagValueSplitter::apply(series, logger);
73 
74  for(const ::fwMedData::DicomSeries::sptr& dicomSeries : result)
75  {
76  DcmFileFormat fileFormat;
77  OFCondition status;
78  DcmDataset* dataset;
79  OFString data;
80 
81  // Open first instance
82  const auto firstItem = dicomSeries->getDicomContainer().begin();
83  const ::fwMemory::BufferObject::sptr bufferObj = firstItem->second;
84  const size_t buffSize = bufferObj->getSize();
85  const std::string dicomPath = bufferObj->getStreamInfo().fsFile.string();
86  ::fwMemory::BufferObject::Lock lock(bufferObj);
87  char* buffer = static_cast< char* >( lock.getBuffer() );
88 
89  DcmInputBufferStream is;
90  is.setBuffer(buffer, offile_off_t(buffSize));
91  is.setEos();
92 
93  fileFormat.transferInit();
94  if (!fileFormat.read(is).good())
95  {
96  FW_RAISE("Unable to read Dicom file '"<< dicomPath <<"' "<<
97  "(slice: '" << firstItem->first << "')");
98  }
99 
100  fileFormat.loadAllDataIntoMemory();
101  fileFormat.transferEnd();
102 
103  dataset = fileFormat.getDataset();
104 
105  // Read SOPClassUID
106  dataset = fileFormat.getDataset();
107  status = dataset->findAndGetOFStringArray(DCM_SOPClassUID, data);
108  FW_RAISE_IF("Unable to read tags: \""+dicomPath+"\"", status.bad());
109 
110  ::fwMedData::DicomSeries::SOPClassUIDContainerType sopClassUIDContainer;
111  sopClassUIDContainer.insert(data.c_str());
112  dicomSeries->setSOPClassUIDs(sopClassUIDContainer);
113  }
114 
115  if(result.size() > 1)
116  {
117  logger->warning("The same series instance UID has been used for several instances "
118  "with different SOP class UID. The series has been split.");
119  }
120 
121  return result;
122 }
123 
124 } // namespace splitter
125 } // namespace fwDicomIOFilter
virtual FWDICOMIOFILTER_API std::string getDescription() const override
Return the description of the filter.
static const std::string s_FILTER_NAME
Filter name.
static const std::string s_FILTER_DESCRIPTION
Filter description.
FWDICOMIOFILTER_API SOPClassUIDSplitter(::fwDicomIOFilter::IFilter::Key key)
Constructor.
fwDicomIOFilter contains filters used to pre-process images before reading.
base class for BufferObject Lock
virtual FWDICOMIOFILTER_API ~SOPClassUIDSplitter()
Destructor.
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.
Filter that uses the SOPClassUID tag to split the instances.
virtual FWDICOMIOFILTER_API std::string getName() const override
Return the name of the filter.
void setTag(const DcmTagKey &_tag)
Tag used to sort instances.
virtual FWDICOMIOFILTER_API DicomSeriesContainerType apply(const ::fwMedData::DicomSeries::sptr &series, const ::fwLog::Logger::sptr &logger) const override
Override.
Filter that uses a tag to split the instances.
virtual FWDICOMIOFILTER_API bool isConfigurationRequired() const override
Return true if a configuration is required.