gdcmDataSet.h
Go to the documentation of this file.
/*=========================================================================
Program: GDCM (Grassroots DICOM). A DICOM library
Copyright (c) 2006-2011 Mathieu Malaterre
All rights reserved.
See Copyright.txt or http://gdcm.sourceforge.net/Copyright.html for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#ifndef GDCMDATASET_H
#define GDCMDATASET_H
#include "gdcmDataElement.h"
#include "gdcmTag.h"
#include "gdcmVR.h"
#include "gdcmElement.h"
#include "gdcmMediaStorage.h"
#include <set>
#include <iterator>
namespace gdcm_ns
{
class GDCM_EXPORT DataElementException : public std::exception {};
class PrivateTag;
class GDCM_EXPORT DataSet
{
friend class CSAHeader;
public:
typedef std::set<DataElement> DataElementSet;
typedef DataElementSet::const_iterator ConstIterator;
typedef DataElementSet::iterator Iterator;
typedef DataElementSet::size_type SizeType;
//typedef typename DataElementSet::iterator iterator;
ConstIterator Begin() const { return DES.begin(); }
Iterator Begin() { return DES.begin(); }
ConstIterator End() const { return DES.end(); }
Iterator End() { return DES.end(); }
const DataElementSet &GetDES() const { return DES; }
DataElementSet &GetDES() { return DES; }
void Clear() {
DES.clear();
assert( DES.empty() );
}
SizeType Size() const {
return DES.size();
}
void Print(std::ostream &os, std::string const &indent = "") const {
// CT_Phillips_JPEG2K_Decompr_Problem.dcm has a SQ of length == 0
//int s = DES.size();
//assert( s );
//std::copy(DES.begin(), DES.end(),
// std::ostream_iterator<DataElement>(os, "\n"));
ConstIterator it = DES.begin();
for( ; it != DES.end(); ++it)
{
os << indent << *it << "\n";
}
}
template <typename TDE>
unsigned int ComputeGroupLength(Tag const &tag) const
{
assert( tag.GetElement() == 0x0 );
const DataElement r(tag);
ConstIterator it = DES.find(r);
unsigned int res = 0;
for( ++it; it != DES.end()
&& it->GetTag().GetGroup() == tag.GetGroup(); ++it)
{
assert( it->GetTag().GetElement() != 0x0 );
assert( it->GetTag().GetGroup() == tag.GetGroup() );
res += it->GetLength<TDE>();
}
return res;
}
template <typename TDE>
VL GetLength() const {
if( DES.empty() ) return 0;
assert( !DES.empty() );
VL ll = 0;
assert( ll == 0 );
ConstIterator it = DES.begin();
for( ; it != DES.end(); ++it)
{
assert( !(it->GetLength<TDE>().IsUndefined()) );
if ( it->GetTag() != Tag(0xfffe,0xe00d) )
{
ll += it->GetLength<TDE>();
}
}
return ll;
}
void Insert(const DataElement& de) {
// FIXME: there is a special case where a dataset can have value < 0x8, see:
// $ gdcmdump --csa gdcmData/SIEMENS-JPEG-CorruptFrag.dcm
if( de.GetTag().GetGroup() >= 0x0008 || de.GetTag().GetGroup() == 0x4 )
{
// prevent user error:
if( de.GetTag() == Tag(0xfffe,0xe00d)
|| de.GetTag() == Tag(0xfffe,0xe0dd)
|| de.GetTag() == Tag(0xfffe,0xe000) )
{
}
else
{
InsertDataElement( de );
}
}
else
{
gdcmErrorMacro( "Cannot add element with group < 0x0008 and != 0x4 in the dataset: " << de.GetTag() );
}
}
void Replace(const DataElement& de) {
ConstIterator it = DES.find(de);
if( it != DES.end() )
{
// detect loop:
gdcmAssertAlwaysMacro( &*it != &de );
DES.erase(it);
}
DES.insert(de);
}
void ReplaceEmpty(const DataElement& de) {
ConstIterator it = DES.find(de);
if( it != DES.end() && it->IsEmpty() )
{
// detect loop:
gdcmAssertAlwaysMacro( &*it != &de );
DES.erase(it);
}
DES.insert(de);
}
SizeType Remove(const Tag& tag) {
DataElementSet::size_type count = DES.erase(tag);
assert( count == 0 || count == 1 );
return count;
}
//DataElement& GetDataElement(const Tag &t) {
// DataElement r(t);
// Iterator it = DES.find(r);
// if( it != DES.end() )
// return *it;
// return GetDEEnd();
// }
const DataElement& GetDataElement(const Tag &t) const {
const DataElement r(t);
ConstIterator it = DES.find(r);
if( it != DES.end() )
return *it;
return GetDEEnd();
}
const DataElement& operator[] (const Tag &t) const { return GetDataElement(t); }
const DataElement& operator() (uint16_t group, uint16_t element) const { return GetDataElement( Tag(group,element) ); }
std::string GetPrivateCreator(const Tag &t) const;
PrivateTag GetPrivateTag(const Tag &t) const;
bool FindDataElement(const PrivateTag &t) const;
const DataElement& GetDataElement(const PrivateTag &t) const;
// DUMB: this only search within the level of the current DataSet
bool FindDataElement(const Tag &t) const {
const auto it = GetDataElement(t);
// Return if tag is found
return it != GetDEEnd();
}
// WARNING:
// This only search at the same level as the DataSet is !
const DataElement& FindNextDataElement(const Tag &t) const {
const DataElement r(t);
ConstIterator it = DES.lower_bound(r);
if( it != DES.end() )
return *it;
return GetDEEnd();
}
bool IsEmpty() const { return DES.empty(); }
DataSet& operator=(DataSet const &)
= default;
template <typename TDE, typename TSwap>
std::istream &ReadNested(std::istream &is);
template <typename TDE, typename TSwap>
std::istream &Read(std::istream &is);
template <typename TDE, typename TSwap>
std::istream &ReadUpToTag(std::istream &is, const Tag &t, std::set<Tag> const & skiptags);
template <typename TDE, typename TSwap>
std::istream &ReadUpToTagWithLength(std::istream &is, const Tag &t, std::set<Tag> const & skiptags, VL & length);
template <typename TDE, typename TSwap>
std::istream &ReadSelectedTags(std::istream &is, const std::set<Tag> & tags, bool readvalues = true);
template <typename TDE, typename TSwap>
std::istream &ReadSelectedTagsWithLength(std::istream &is, const std::set<Tag> & tags, VL & length, bool readvalues = true);
template <typename TDE, typename TSwap>
std::istream &ReadSelectedPrivateTags(std::istream &is, const std::set<PrivateTag> & tags, bool readvalues = true);
template <typename TDE, typename TSwap>
std::istream &ReadSelectedPrivateTagsWithLength(std::istream &is, const std::set<PrivateTag> & tags, VL & length, bool readvalues = true);
template <typename TDE, typename TSwap>
std::ostream const &Write(std::ostream &os) const;
template <typename TDE, typename TSwap>
std::istream &ReadWithLength(std::istream &is, VL &length);
MediaStorage GetMediaStorage() const;
protected:
/* GetDEEnd is a Win32 only issue, one cannot use a dllexported
* static member data in an inline function, otherwise symbol
* will get reported as missing in any dll using the inlined function
*/
const DataElement& GetDEEnd() const;
// This function is not safe, it does not check for the value of the tag
// so depending whether we are getting called from a dataset or file meta header
// the condition is different
void InsertDataElement(const DataElement& de) {
//if( de.GetTag() == Tag(0xfffe,0xe00d) ) return;
//if( de.GetTag() == Tag(0xfffe,0xe0dd) ) return;
#ifndef NDEBUG
std::pair<Iterator,bool> pr = DES.insert(de);
if( pr.second == false )
{
gdcmWarningMacro( "DataElement: " << de << " was already found, skipping duplicate entry.\n"
"Original entry kept is: " << *pr.first );
}
#else
DES.insert(de);
#endif
assert( de.IsEmpty() || de.GetVL() == de.GetValue().GetLength() );
}
protected:
// Internal function, that will compute the actual Tag (if found) of
// a requested Private Tag (XXXX,YY,"PRIVATE")
Tag ComputeDataElement(const PrivateTag & t) const;
private:
DataElementSet DES;
static DataElement DEEnd;
friend std::ostream& operator<<(std::ostream &_os, const DataSet &);
};
//-----------------------------------------------------------------------------
inline std::ostream& operator<<(std::ostream &os, const DataSet &val)
{
val.Print(os);
return os;
}
#if defined(SWIGPYTHON) || defined(SWIGCSHARP) || defined(SWIGJAVA) || defined(SWIGPHP)
/*
* HACK: I need this temp class to be able to manipulate a std::set from python,
* swig does not support wrapping of simple class like std::set...
*/
class SWIGDataSet
{
public:
SWIGDataSet(DataSet &des):Internal(des),it(des.Begin()) {}
const DataElement& GetCurrent() const { return *it; }
void Start() { it = Internal.Begin(); }
bool IsAtEnd() const { return it == Internal.End(); }
void Next() { ++it; }
private:
DataSet & Internal;
DataSet::ConstIterator it;
};
#endif /* SWIG */
} // end namespace gdcm_ns
#include "gdcmDataSet.txx"
#endif //GDCMDATASET_H
gdcm::DataElementException
Definition gdcmDataSet.h:28
gdcm::DataElement
Class to represent a Data Element either Implicit or Explicit.
Definition gdcmDataElement.h:59
gdcm::DataElement::GetVL
const VL & GetVL() const
Get VL.
Definition gdcmDataElement.h:74
gdcm::DataElement::GetTag
const Tag & GetTag() const
Get Tag.
Definition gdcmDataElement.h:67
gdcm::DataElement::IsEmpty
bool IsEmpty() const
Check if Data Element is empty.
Definition gdcmDataElement.h:106
gdcm::DataElement::GetValue
Value const & GetValue() const
Set/Get Value (bytes array, SQ of items, SQ of fragments):
Definition gdcmDataElement.h:94
gdcm::DataSet
Class to represent a Data Set (which contains Data Elements).
Definition gdcmDataSet.h:56
gdcm::DataSet::Iterator
DataElementSet::iterator Iterator
Definition gdcmDataSet.h:61
gdcm::DataSet::GetDataElement
const DataElement & GetDataElement(const Tag &t) const
Definition gdcmDataSet.h:188
gdcm::DataSet::operator=
DataSet & operator=(DataSet const &)=default
gdcm::DataSet::InsertDataElement
void InsertDataElement(const DataElement &de)
Definition gdcmDataSet.h:273
gdcm::DataSet::ComputeDataElement
Tag ComputeDataElement(const PrivateTag &t) const
gdcm::DataSet::ReadSelectedTags
std::istream & ReadSelectedTags(std::istream &is, const std::set< Tag > &tags, bool readvalues=true)
gdcm::DataSet::End
Iterator End()
Definition gdcmDataSet.h:67
gdcm::DataSet::GetPrivateTag
PrivateTag GetPrivateTag(const Tag &t) const
Return the private tag of the private tag 't', private creator will be set to empty if not found.
gdcm::DataSet::Clear
void Clear()
Definition gdcmDataSet.h:70
gdcm::DataSet::FindNextDataElement
const DataElement & FindNextDataElement(const Tag &t) const
Definition gdcmDataSet.h:219
gdcm::DataSet::ReplaceEmpty
void ReplaceEmpty(const DataElement &de)
Only replace a DICOM attribute when it is missing or empty.
Definition gdcmDataSet.h:161
gdcm::DataSet::FindDataElement
bool FindDataElement(const PrivateTag &t) const
Look up if private tag 't' is present in the dataset:
gdcm::DataSet::GetMediaStorage
MediaStorage GetMediaStorage() const
gdcm::DataSet::GetPrivateCreator
std::string GetPrivateCreator(const Tag &t) const
gdcm::DataSet::ConstIterator
DataElementSet::const_iterator ConstIterator
Definition gdcmDataSet.h:60
gdcm::DataSet::GetDES
const DataElementSet & GetDES() const
Definition gdcmDataSet.h:68
gdcm::DataSet::IsEmpty
bool IsEmpty() const
Returns if the dataset is empty.
Definition gdcmDataSet.h:228
gdcm::DataSet::Read
std::istream & Read(std::istream &is)
gdcm::DataSet::Remove
SizeType Remove(const Tag &tag)
Completely remove a dataelement from the dataset.
Definition gdcmDataSet.h:172
gdcm::DataSet::GetDataElement
const DataElement & GetDataElement(const PrivateTag &t) const
Return the dataelement.
gdcm::DataSet::ReadNested
std::istream & ReadNested(std::istream &is)
gdcm::DataSet::SizeType
DataElementSet::size_type SizeType
Definition gdcmDataSet.h:62
gdcm::DataSet::ReadSelectedPrivateTags
std::istream & ReadSelectedPrivateTags(std::istream &is, const std::set< PrivateTag > &tags, bool readvalues=true)
gdcm::DataSet::CSAHeader
friend class CSAHeader
Definition gdcmDataSet.h:57
gdcm::DataSet::Write
std::ostream const & Write(std::ostream &os) const
gdcm::DataSet::Insert
void Insert(const DataElement &de)
Definition gdcmDataSet.h:128
gdcm::DataSet::Begin
ConstIterator Begin() const
Definition gdcmDataSet.h:64
gdcm::DataSet::Begin
Iterator Begin()
Definition gdcmDataSet.h:65
gdcm::DataSet::ReadSelectedTagsWithLength
std::istream & ReadSelectedTagsWithLength(std::istream &is, const std::set< Tag > &tags, VL &length, bool readvalues=true)
gdcm::DataSet::operator<<
friend std::ostream & operator<<(std::ostream &_os, const DataSet &)
Definition gdcmDataSet.h:300
gdcm::DataSet::Print
void Print(std::ostream &os, std::string const &indent="") const
Definition gdcmDataSet.h:79
gdcm::DataSet::DataElementSet
std::set< DataElement > DataElementSet
Definition gdcmDataSet.h:59
gdcm::DataSet::GetLength
VL GetLength() const
Definition gdcmDataSet.h:110
gdcm::DataSet::FindDataElement
bool FindDataElement(const Tag &t) const
Definition gdcmDataSet.h:211
gdcm::DataSet::ReadUpToTagWithLength
std::istream & ReadUpToTagWithLength(std::istream &is, const Tag &t, std::set< Tag > const &skiptags, VL &length)
gdcm::DataSet::Size
SizeType Size() const
Definition gdcmDataSet.h:75
gdcm::DataSet::Replace
void Replace(const DataElement &de)
Replace a dataelement with another one.
Definition gdcmDataSet.h:150
gdcm::DataSet::ComputeGroupLength
unsigned int ComputeGroupLength(Tag const &tag) const
Definition gdcmDataSet.h:93
gdcm::DataSet::GetDEEnd
const DataElement & GetDEEnd() const
gdcm::DataSet::ReadWithLength
std::istream & ReadWithLength(std::istream &is, VL &length)
gdcm::DataSet::GetDES
DataElementSet & GetDES()
Definition gdcmDataSet.h:69
gdcm::DataSet::ReadUpToTag
std::istream & ReadUpToTag(std::istream &is, const Tag &t, std::set< Tag > const &skiptags)
gdcm::DataSet::ReadSelectedPrivateTagsWithLength
std::istream & ReadSelectedPrivateTagsWithLength(std::istream &is, const std::set< PrivateTag > &tags, VL &length, bool readvalues=true)
gdcm::DataSet::End
ConstIterator End() const
Definition gdcmDataSet.h:66
gdcm::MediaStorage
MediaStorage.
Definition gdcmMediaStorage.h:44
gdcm::PrivateTag
Class to represent a Private DICOM Data Element (Attribute) Tag (Group, Element, Owner).
Definition gdcmPrivateTag.h:39
gdcm::Tag
Class to represent a DICOM Data Element (Attribute) Tag (Group, Element).
Definition gdcmTag.h:39
gdcm::Tag::GetGroup
uint16_t GetGroup() const
Returns the 'Group number' of the given Tag.
Definition gdcmTag.h:55
gdcm::Tag::GetElement
uint16_t GetElement() const
Returns the 'Element number' of the given Tag.
Definition gdcmTag.h:57
gdcm::VL
Value Length.
Definition gdcmVL.h:30
gdcm::Value::GetLength
virtual VL GetLength() const =0
gdcmDataElement.h
gdcmElement.h
gdcmMediaStorage.h
gdcmTag.h
gdcmAssertAlwaysMacro
#define gdcmAssertAlwaysMacro(arg)
AssertAlways.
Definition gdcmTrace.h:228
gdcmWarningMacro
#define gdcmWarningMacro(msg)
Warning.
Definition gdcmTrace.h:142
gdcmErrorMacro
#define gdcmErrorMacro(msg)
Error this is pretty bad, more than just warning It could mean lost of data, something not handle....
Definition gdcmTrace.h:165
gdcmVR.h
GDCM_EXPORT
#define GDCM_EXPORT
Definition gdcmWin32.h:34