7 #include "fwDicomIOFilter/splitter/TagValueSplitter.hpp" 9 #include "fwDicomIOFilter/exceptions/FilterFailure.hpp" 10 #include "fwDicomIOFilter/registry/macros.hpp" 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> 28 "Split instances according to a tag value.";
35 m_tag = DCM_UndefinedTagKey;
68 const ::fwMedData::DicomSeries::sptr& series,
69 const ::fwLog::Logger::sptr& logger)
const 71 if(
m_tag == DCM_UndefinedTagKey)
73 const std::string msg =
"Unable to split the series, the specified tag is not valid.";
74 throw ::fwDicomIOFilter::exceptions::FilterFailure(msg);
77 DicomSeriesContainerType result;
79 typedef std::vector< ::fwMemory::BufferObject::sptr > InstanceContainerType;
80 typedef std::map< std::string, InstanceContainerType > InstanceGroupContainer;
83 InstanceGroupContainer groupContainer;
89 for(
const auto& item : series->getDicomContainer())
91 const ::fwMemory::BufferObject::sptr bufferObj = item.second;
92 const size_t buffSize = bufferObj->getSize();
94 char* buffer =
static_cast< char*
>( lock.
getBuffer() );
96 DcmInputBufferStream is;
97 is.setBuffer(buffer, offile_off_t(buffSize));
100 DcmFileFormat fileFormat;
101 fileFormat.transferInit();
102 if (!fileFormat.read(is).good())
104 FW_RAISE(
"Unable to read Dicom file '"<< bufferObj->getStreamInfo().fsFile.string() <<
"' "<<
105 "(slice: '" << item.first <<
"')");
108 fileFormat.loadAllDataIntoMemory();
109 fileFormat.transferEnd();
111 dataset = fileFormat.getDataset();
114 dataset->findAndGetOFStringArray(
m_tag, data);
115 const std::string value = data.c_str();
118 groupContainer[value].push_back(bufferObj);
121 for(
const InstanceGroupContainer::value_type& group : groupContainer)
124 ::fwMedData::DicomSeries::sptr dicomSeries = ::fwMedData::DicomSeries::New();
125 dicomSeries->deepCopy(series);
126 dicomSeries->clearDicomContainer();
130 for(const ::fwMemory::BufferObject::sptr& buffer : group.second)
132 dicomSeries->addBinary(index++, buffer);
136 dicomSeries->setNumberOfInstances(dicomSeries->getDicomContainer().size());
138 result.push_back(dicomSeries);
141 if(result.size() > 1)
143 std::stringstream ss;
144 ss <<
"Series has been split according to the tag value (" <<
145 std::hex << std::setfill(
'0') << std::setw(4) <<
m_tag.getGroup() <<
"," <<
146 std::hex << std::setfill(
'0') << std::setw(4) <<
m_tag.getElement() <<
").";
147 logger->warning(ss.str());
FWDICOMIOFILTER_API TagValueSplitter(::fwDicomIOFilter::IFilter::Key key)
Constructor.
fwDicomIOFilter contains filters used to pre-process images before reading.
base class for BufferObject Lock
static const std::string s_FILTER_NAME
Filter name.
virtual FWDICOMIOFILTER_API std::string getName() const override
Return the name of the filter.
virtual FWDICOMIOFILTER_API ~TagValueSplitter()
Destructor.
virtual FWDICOMIOFILTER_API std::string getDescription() const override
Return the description of the filter.
LockBase< T >::BufferType getBuffer() const
Returns BufferObject's buffer pointer.
Key class used to restrict access to Filter construction. See http://www.drdobbs.com/184402053.
static const std::string s_FILTER_DESCRIPTION
Filter description.
DcmTagKey m_tag
Tag used to sort instances.
virtual FWDICOMIOFILTER_API DicomSeriesContainerType apply(const ::fwMedData::DicomSeries::sptr &series, const ::fwLog::Logger::sptr &logger) const override
Override.
virtual FWDICOMIOFILTER_API bool isConfigurationRequired() const override
Return true if a configuration is required.
Filter that uses a tag to split the instances.
Base class for Dicom instance splitter.