gdcmSequenceOfItems.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 GDCMSEQUENCEOFITEMS_H
#define GDCMSEQUENCEOFITEMS_H
#include "gdcmValue.h"
#include "gdcmItem.h"
#include <vector>
#include <cstring> // strcmp
namespace gdcm_ns
{
class GDCM_EXPORT SequenceOfItems : public Value
{
public:
// Typdefs:
typedef std::vector< Item > ItemVector;
typedef ItemVector::size_type SizeType;
typedef ItemVector::iterator Iterator;
typedef ItemVector::const_iterator ConstIterator;
Iterator Begin() { return Items.begin(); }
Iterator End() { return Items.end(); }
ConstIterator Begin() const { return Items.begin(); }
ConstIterator End() const { return Items.end(); }
SequenceOfItems():SequenceLengthField(0xFFFFFFFF) { }
//SequenceOfItems(VL const &vl = 0xFFFFFFFF):SequenceLengthField(vl),NType(type) { }
VL GetLength() const override { return SequenceLengthField; }
void SetLength(VL length) override {
SequenceLengthField = length;
}
void SetLengthToUndefined();
bool IsUndefinedLength() const {
return SequenceLengthField.IsUndefined();
}
template <typename TDE>
VL ComputeLength() const;
void Clear() override;
void AddItem(Item const &item);
Item & AddNewUndefinedLengthItem();
bool RemoveItemByIndex( const SizeType index );
bool IsEmpty() const { return Items.empty(); }
SizeType GetNumberOfItems() const { return Items.size(); }
void SetNumberOfItems(SizeType n) { Items.resize(n); }
/* WARNING: first item is #1 (see DICOM standard)
* Each Item shall be implicitly assigned an ordinal position starting with the value 1 for the
* first Item in the Sequence, and incremented by 1 with each subsequent Item. The last Item in the
* Sequence shall have an ordinal position equal to the number of Items in the Sequence.
*/
const Item &GetItem(SizeType position) const;
Item &GetItem(SizeType position);
SequenceOfItems &operator=(const SequenceOfItems &val) {
SequenceLengthField = val.SequenceLengthField;
Items = val.Items;
return *this;
}
template <typename TDE, typename TSwap>
std::istream &Read(std::istream &is, bool readvalues = true)
{
(void)readvalues;
const Tag seqDelItem(0xfffe,0xe0dd);
if( SequenceLengthField.IsUndefined() )
{
Item item;
while( item.Read<TDE,TSwap>(is) && item.GetTag() != seqDelItem )
{
//gdcmDebugMacro( "Item: " << item );
assert( item.GetTag() != seqDelItem );
Items.push_back( item );
item.Clear();
}
//assert( item.GetTag() == seqDelItem && item.GetVL() == 0 );
}
else
{
Item item;
VL l = 0;
//is.seekg( SequenceLengthField, std::ios::cur ); return is;
while( l != SequenceLengthField )
{
try
{
item.Read<TDE,TSwap>(is);
}
catch( Exception &ex )
{
if( strcmp( ex.GetDescription(), "Changed Length" ) == 0 )
{
VL newlength = l + item.template GetLength<TDE>();
if( newlength > SequenceLengthField )
{
// BogugsItemAndSequenceLength.dcm
gdcmWarningMacro( "SQ length is wrong" );
SequenceLengthField = newlength;
}
}
else
{
throw ex;
}
}
#ifdef GDCM_SUPPORT_BROKEN_IMPLEMENTATION
if( item.GetTag() == seqDelItem )
{
gdcmWarningMacro( "SeqDelItem found in defined length Sequence. Skipping" );
assert( item.GetVL() == 0 );
assert( item.GetNestedDataSet().Size() == 0 );
// we need to pay attention that the length of the Sequence of Items will be wrong
// this way. Indeed by not adding this item we are changing the size of this sqi
}
else // Not a seq del item marker
#endif
{
// By design we never load them. If we were to load those attribute
// as normal item it would become very complex to convert a sequence
// from defined length to undefined length with the risk to write two
// seq del marker
Items.push_back( item );
}
l += item.template GetLength<TDE>();
if( l > SequenceLengthField )
{
gdcmDebugMacro( "Found: Length of Item larger than expected" );
throw "Length of Item larger than expected";
}
assert( l <= SequenceLengthField );
//std::cerr << "sqi debug len: " << is.tellg() << " " << l << " " << SequenceLengthField << std::endl;
#ifdef GDCM_SUPPORT_BROKEN_IMPLEMENTATION
// MR_Philips_Intera_No_PrivateSequenceImplicitVR.dcm
// (0x2005, 0x1080): for some reason computation of length fails...
if( SequenceLengthField == 778 && l == 774 )
{
gdcmWarningMacro( "PMS: Super bad hack" );
SequenceLengthField = l;
throw Exception( "Wrong Length" );
//l = SequenceLengthField;
}
// Bug_Philips_ItemTag_3F3F
// (0x2005, 0x1080): Because we do not handle fully the bug at the item
// level we need to check here too
else if ( SequenceLengthField == 444 && l == 3*71 )
{
// This one is a double bug. Item length is wrong and impact SQ length
gdcmWarningMacro( "PMS: Super bad hack" );
l = SequenceLengthField;
}
#endif
}
assert( l == SequenceLengthField );
}
return is;
}
template <typename TDE,typename TSwap>
std::ostream const &Write(std::ostream &os) const
{
typename ItemVector::const_iterator it = Items.begin();
for(;it != Items.end(); ++it)
{
it->Write<TDE,TSwap>(os);
}
if( SequenceLengthField.IsUndefined() )
{
// seq del item is not stored, write it !
const Tag seqDelItem(0xfffe,0xe0dd);
seqDelItem.Write<TSwap>(os);
VL zero = 0;
zero.Write<TSwap>(os);
}
return os;
}
//protected:
void Print(std::ostream &os) const override {
os << "\t(" << SequenceLengthField << ")\n";
ItemVector::const_iterator it =
Items.begin();
for(;it != Items.end(); ++it)
{
os << " " << *it;
}
if( SequenceLengthField.IsUndefined() )
{
const Tag seqDelItem(0xfffe,0xe0dd);
VL zero = 0;
os << seqDelItem;
os << "\t" << zero;
}
}
static SmartPointer<SequenceOfItems> New()
{
return new SequenceOfItems;
}
bool FindDataElement(const Tag &t) const;
bool operator==(const Value &val) const override
{
const SequenceOfItems &sqi = dynamic_cast<const SequenceOfItems&>(val);
return SequenceLengthField == sqi.SequenceLengthField &&
Items == sqi.Items;
}
private:
public:
VL SequenceLengthField;
ItemVector Items;
};
} // end namespace gdcm_ns
#include "gdcmSequenceOfItems.txx"
#endif //GDCMSEQUENCEOFITEMS_H
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::DataSet::Size
SizeType Size() const
Definition gdcmDataSet.h:75
gdcm::Exception
Exception.
Definition gdcmException.h:44
gdcm::Exception::GetDescription
const char * GetDescription() const
Return the Description.
Definition gdcmException.h:92
gdcm::Item
Class to represent an Item.
Definition gdcmItem.h:46
gdcm::Item::Clear
void Clear()
Definition gdcmItem.h:51
gdcm::Item::Read
std::istream & Read(std::istream &is)
Definition gdcmItem.h:97
gdcm::Item::GetNestedDataSet
const DataSet & GetNestedDataSet() const
Definition gdcmItem.h:80
gdcm::SequenceOfItems::ConstIterator
ItemVector::const_iterator ConstIterator
Definition gdcmSequenceOfItems.h:46
gdcm::SequenceOfItems::SequenceLengthField
VL SequenceLengthField
Total length of the Sequence (or 0xffffffff) if undefined.
Definition gdcmSequenceOfItems.h:254
gdcm::SequenceOfItems::ItemVector
std::vector< Item > ItemVector
Definition gdcmSequenceOfItems.h:43
gdcm::SequenceOfItems::GetNumberOfItems
SizeType GetNumberOfItems() const
Definition gdcmSequenceOfItems.h:86
gdcm::SequenceOfItems::Print
void Print(std::ostream &os) const override
Definition gdcmSequenceOfItems.h:221
gdcm::SequenceOfItems::operator==
bool operator==(const Value &val) const override
Definition gdcmSequenceOfItems.h:244
gdcm::SequenceOfItems::Read
std::istream & Read(std::istream &is, bool readvalues=true)
Definition gdcmSequenceOfItems.h:104
gdcm::SequenceOfItems::operator=
SequenceOfItems & operator=(const SequenceOfItems &val)
Definition gdcmSequenceOfItems.h:97
gdcm::SequenceOfItems::Begin
ConstIterator Begin() const
Definition gdcmSequenceOfItems.h:49
gdcm::SequenceOfItems::SetLength
void SetLength(VL length) override
Sets the actual SQ length.
Definition gdcmSequenceOfItems.h:59
gdcm::SequenceOfItems::RemoveItemByIndex
bool RemoveItemByIndex(const SizeType index)
gdcm::SequenceOfItems::SetNumberOfItems
void SetNumberOfItems(SizeType n)
Definition gdcmSequenceOfItems.h:87
gdcm::SequenceOfItems::Write
std::ostream const & Write(std::ostream &os) const
Definition gdcmSequenceOfItems.h:201
gdcm::SequenceOfItems::AddItem
void AddItem(Item const &item)
Appends an Item to the already added ones.
gdcm::SequenceOfItems::Clear
void Clear() override
remove all items within the sequence
gdcm::SequenceOfItems::GetLength
VL GetLength() const override
Returns the SQ length, as read from disk.
Definition gdcmSequenceOfItems.h:57
gdcm::SequenceOfItems::IsUndefinedLength
bool IsUndefinedLength() const
return if Value Length if of undefined length
Definition gdcmSequenceOfItems.h:65
gdcm::SequenceOfItems::FindDataElement
bool FindDataElement(const Tag &t) const
gdcm::SequenceOfItems::GetItem
Item & GetItem(SizeType position)
gdcm::SequenceOfItems::Items
ItemVector Items
Vector of Sequence Items.
Definition gdcmSequenceOfItems.h:256
gdcm::SequenceOfItems::New
static SmartPointer< SequenceOfItems > New()
Definition gdcmSequenceOfItems.h:238
gdcm::SequenceOfItems::Iterator
ItemVector::iterator Iterator
Definition gdcmSequenceOfItems.h:45
gdcm::SequenceOfItems::End
ConstIterator End() const
Definition gdcmSequenceOfItems.h:50
gdcm::SequenceOfItems::End
Iterator End()
Definition gdcmSequenceOfItems.h:48
gdcm::SequenceOfItems::GetItem
const Item & GetItem(SizeType position) const
gdcm::SequenceOfItems::SetLengthToUndefined
void SetLengthToUndefined()
Properly set the Sequence of Item to be undefined length.
gdcm::SequenceOfItems::AddNewUndefinedLengthItem
Item & AddNewUndefinedLengthItem()
Appends an Item to the already added ones.
gdcm::SequenceOfItems::Begin
Iterator Begin()
Definition gdcmSequenceOfItems.h:47
gdcm::SequenceOfItems::SequenceOfItems
SequenceOfItems()
constructor (UndefinedLength by default)
Definition gdcmSequenceOfItems.h:53
gdcm::SequenceOfItems::IsEmpty
bool IsEmpty() const
Definition gdcmSequenceOfItems.h:85
gdcm::SequenceOfItems::ComputeLength
VL ComputeLength() const
gdcm::SequenceOfItems::SizeType
ItemVector::size_type SizeType
Definition gdcmSequenceOfItems.h:44
gdcm::SmartPointer
Class for Smart Pointer.
Definition gdcmSmartPointer.h:40
gdcm::Tag
Class to represent a DICOM Data Element (Attribute) Tag (Group, Element).
Definition gdcmTag.h:39
gdcm::Tag::Write
const std::ostream & Write(std::ostream &os) const
Write a tag in binary rep.
Definition gdcmTag.h:169
gdcm::VL
Value Length.
Definition gdcmVL.h:30
gdcm::VL::Write
const std::ostream & Write(std::ostream &os) const
Definition gdcmVL.h:99
gdcm::Value::Value
Value()=default
gdcmItem.h
gdcmWarningMacro
#define gdcmWarningMacro(msg)
Warning.
Definition gdcmTrace.h:142
gdcmDebugMacro
#define gdcmDebugMacro(msg)
Debug.
Definition gdcmTrace.h:119
gdcmValue.h
GDCM_EXPORT
#define GDCM_EXPORT
Definition gdcmWin32.h:34