GDCM 3.2.1

gdcmSequenceOfItems.h
Go to the documentation of this file.
1/*=========================================================================
2
3 Program: GDCM (Grassroots DICOM). A DICOM library
4
5 Copyright (c) 2006-2011 Mathieu Malaterre
6 All rights reserved.
7 See Copyright.txt or http://gdcm.sourceforge.net/Copyright.html for details.
8
9 This software is distributed WITHOUT ANY WARRANTY; without even
10 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11 PURPOSE. See the above copyright notice for more information.
12
13=========================================================================*/
14
15#ifndef GDCMSEQUENCEOFITEMS_H
16#define GDCMSEQUENCEOFITEMS_H
17
18#include "gdcmValue.h"
19#include "gdcmItem.h"
20
21#include <vector>
22#include <cstring> // strcmp
23
24 namespace gdcm_ns
25{
26
39 class GDCM_EXPORT SequenceOfItems : public Value
40{
41 public:
42 // Typdefs:
43 typedef std::vector< Item > ItemVector;
44 typedef ItemVector::size_type SizeType;
45 typedef ItemVector::iterator Iterator;
46 typedef ItemVector::const_iterator ConstIterator;
47 Iterator Begin() { return Items.begin(); }
48 Iterator End() { return Items.end(); }
49 ConstIterator Begin() const { return Items.begin(); }
50 ConstIterator End() const { return Items.end(); }
51
53 SequenceOfItems():SequenceLengthField(0xFFFFFFFF) { }
54 //SequenceOfItems(VL const &vl = 0xFFFFFFFF):SequenceLengthField(vl),NType(type) { }
55
57 VL GetLength() const override { return SequenceLengthField; }
59 void SetLength(VL length) override {
60 SequenceLengthField = length;
61 }
62
63 void SetLengthToUndefined();
65 bool IsUndefinedLength() const {
66 return SequenceLengthField.IsUndefined();
67 }
68
69 template <typename TDE>
70 VL ComputeLength() const;
71
73 void Clear() override;
74
76 void AddItem(Item const &item);
77
79 Item & AddNewUndefinedLengthItem();
80
83 bool RemoveItemByIndex( const SizeType index );
84
85 bool IsEmpty() const { return Items.empty(); }
86 SizeType GetNumberOfItems() const { return Items.size(); }
87 void SetNumberOfItems(SizeType n) { Items.resize(n); }
88
89 /* WARNING: first item is #1 (see DICOM standard)
90 * Each Item shall be implicitly assigned an ordinal position starting with the value 1 for the
91 * first Item in the Sequence, and incremented by 1 with each subsequent Item. The last Item in the
92 * Sequence shall have an ordinal position equal to the number of Items in the Sequence.
93 */
94 const Item &GetItem(SizeType position) const;
95 Item &GetItem(SizeType position);
96
97 SequenceOfItems &operator=(const SequenceOfItems &val) {
98 SequenceLengthField = val.SequenceLengthField;
99 Items = val.Items;
100 return *this;
101 }
102
103 template <typename TDE, typename TSwap>
104 std::istream &Read(std::istream &is, bool readvalues = true)
105 {
106 (void)readvalues;
107 const Tag seqDelItem(0xfffe,0xe0dd);
108 if( SequenceLengthField.IsUndefined() )
109 {
110 Item item;
111 while( item.Read<TDE,TSwap>(is) && item.GetTag() != seqDelItem )
112 {
113 //gdcmDebugMacro( "Item: " << item );
114 gdcm_assert( item.GetTag() != seqDelItem );
115 Items.push_back( item );
116 item.Clear();
117 }
118 //gdcm_assert( item.GetTag() == seqDelItem && item.GetVL() == 0 );
119 }
120 else
121 {
122 Item item;
123 VL l = 0;
124 //is.seekg( SequenceLengthField, std::ios::cur ); return is;
125 while( l != SequenceLengthField )
126 {
127 try
128 {
129 item.Read<TDE,TSwap>(is);
130 }
131 catch( Exception &ex )
132 {
133 if( strcmp( ex.GetDescription(), "Changed Length" ) == 0 )
134 {
135 VL newlength = l + item.template GetLength<TDE>();
136 if( newlength > SequenceLengthField )
137 {
138 // BogugsItemAndSequenceLength.dcm
139 gdcmWarningMacro( "SQ length is wrong" );
140 SequenceLengthField = newlength;
141 }
142 }
143 else
144 {
145 throw ex;
146 }
147 }
148#ifdef GDCM_SUPPORT_BROKEN_IMPLEMENTATION
149 if( item.GetTag() == seqDelItem )
150 {
151 gdcmWarningMacro( "SeqDelItem found in defined length Sequence. Skipping" );
152 gdcm_assert( item.GetVL() == 0 );
153 gdcm_assert( item.GetNestedDataSet().Size() == 0 );
154 // we need to pay attention that the length of the Sequence of Items will be wrong
155 // this way. Indeed by not adding this item we are changing the size of this sqi
156 }
157 else // Not a seq del item marker
158#endif
159 {
160 // By design we never load them. If we were to load those attribute
161 // as normal item it would become very complex to convert a sequence
162 // from defined length to undefined length with the risk to write two
163 // seq del marker
164 Items.push_back( item );
165 }
166 l += item.template GetLength<TDE>();
167 if( l > SequenceLengthField )
168 {
169 gdcmDebugMacro( "Found: Length of Item larger than expected" );
170 throw "Length of Item larger than expected";
171 }
172 gdcm_assert( l <= SequenceLengthField );
173 //std::cerr << "sqi debug len: " << is.tellg() << " " << l << " " << SequenceLengthField << std::endl;
174#ifdef GDCM_SUPPORT_BROKEN_IMPLEMENTATION
175 // MR_Philips_Intera_No_PrivateSequenceImplicitVR.dcm
176 // (0x2005, 0x1080): for some reason computation of length fails...
177 if( SequenceLengthField == 778 && l == 774 )
178 {
179 gdcmWarningMacro( "PMS: Super bad hack" );
180 SequenceLengthField = l;
181 throw Exception( "Wrong Length" );
182 //l = SequenceLengthField;
183 }
184 // Bug_Philips_ItemTag_3F3F
185 // (0x2005, 0x1080): Because we do not handle fully the bug at the item
186 // level we need to check here too
187 else if ( SequenceLengthField == 444 && l == 3*71 )
188 {
189 // This one is a double bug. Item length is wrong and impact SQ length
190 gdcmWarningMacro( "PMS: Super bad hack" );
191 l = SequenceLengthField;
192 }
193#endif
194 }
195 gdcm_assert( l == SequenceLengthField );
196 }
197 return is;
198 }
199
200 template <typename TDE,typename TSwap>
201 std::ostream const &Write(std::ostream &os) const
202 {
203 typename ItemVector::const_iterator it = Items.begin();
204 for(;it != Items.end(); ++it)
205 {
206 it->Write<TDE,TSwap>(os);
207 }
208 if( SequenceLengthField.IsUndefined() )
209 {
210 // seq del item is not stored, write it !
211 const Tag seqDelItem(0xfffe,0xe0dd);
212 seqDelItem.Write<TSwap>(os);
213 VL zero = 0;
214 zero.Write<TSwap>(os);
215 }
216
217 return os;
218 }
219
220//protected:
221 void Print(std::ostream &os) const override {
222 os << "\t(" << SequenceLengthField << ")\n";
223 ItemVector::const_iterator it =
224 Items.begin();
225 for(;it != Items.end(); ++it)
226 {
227 os << " " << *it;
228 }
229 if( SequenceLengthField.IsUndefined() )
230 {
231 const Tag seqDelItem(0xfffe,0xe0dd);
232 VL zero = 0;
233 os << seqDelItem;
234 os << "\t" << zero;
235 }
236 }
237
238 static SmartPointer<SequenceOfItems> New()
239 {
240 return new SequenceOfItems;
241 }
242 bool FindDataElement(const Tag &t) const;
243
244 bool operator==(const Value &val) const override
245 {
246 const SequenceOfItems &sqi = dynamic_cast<const SequenceOfItems&>(val);
247 return SequenceLengthField == sqi.SequenceLengthField &&
248 Items == sqi.Items;
249 }
250
251 private:
252 public:
254 VL SequenceLengthField;
256 ItemVector Items;
257};
258
259} // end namespace gdcm_ns
260
261#include "gdcmSequenceOfItems.txx"
262
263#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:46
gdcm::Exception::GetDescription
const char * GetDescription() const
Return the Description.
Definition gdcmException.h:94
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
gdcm_assert
#define gdcm_assert(cond)
Definition gdcmException.h:104
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