GDCM 2.2.1

- Main Page
- Related Pages
- Namespaces
- Classes
- Files
- Examples

- File List
- File Members

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
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 { return SequenceLengthField; }
59 void SetLength(VL length) {
60 SequenceLengthField = length;
61 }
63 void SetLengthToUndefined();
65 bool IsUndefinedLength() const {
66 return SequenceLengthField.IsUndefined();
67 }
68
69 template <typename TDE>
70 VL ComputeLength() const;
71 void Clear() {}
72
74 void AddItem(Item const &item);
75
76 SizeType GetNumberOfItems() const { return Items.size(); }
77 void SetNumberOfItems(SizeType n) { Items.resize(n); }
78
79 /* WARNING: first item is #1 (see DICOM standard)
80 * Each Item shall be implicitly assigned an ordinal position starting with the value 1 for the
81 * first Item in the Sequence, and incremented by 1 with each subsequent Item. The last Item in the
82 * Sequence shall have an ordinal position equal to the number of Items in the Sequence.
83 */
84 const Item &GetItem(SizeType position) const;
85 Item &GetItem(SizeType position);
86
87 SequenceOfItems &operator=(const SequenceOfItems &val) {
88 SequenceLengthField = val.SequenceLengthField;
89 Items = val.Items;
90 return *this;
91 }
92
93 template <typename TDE, typename TSwap>
94 std::istream &Read(std::istream &is)
95 {
96 const Tag seqDelItem(0xfffe,0xe0dd);
97 if( SequenceLengthField.IsUndefined() )
98 {
99 Item item;
100 while( item.Read<TDE,TSwap>(is) && item.GetTag() != seqDelItem )
101 {
102 //gdcmDebugMacro( "Item: " << item );
103 assert( item.GetTag() != seqDelItem );
104 Items.push_back( item );
105 item.Clear();
106 }
107 //assert( item.GetTag() == seqDelItem && item.GetVL() == 0 );
108 }
109 else
110 {
111 Item item;
112 VL l = 0;
113 //is.seekg( SequenceLengthField, std::ios::cur ); return is;
114 while( l != SequenceLengthField )
115 {
116 try
117 {
118 item.Read<TDE,TSwap>(is);
119 }
120 catch( Exception &ex )
121 {
122 if( strcmp( ex.GetDescription(), "Changed Length" ) == 0 )
123 {
124 VL newlength = l + item.template GetLength<TDE>();
125 if( newlength > SequenceLengthField )
126 {
127 // BogugsItemAndSequenceLength.dcm
128 gdcmWarningMacro( "SQ length is wrong" );
129 SequenceLengthField = newlength;
130 }
131 }
132 else
133 {
134 throw ex;
135 }
136 }
137 #ifdef GDCM_SUPPORT_BROKEN_IMPLEMENTATION
138 if( item.GetTag() == seqDelItem )
139 {
140 gdcmWarningMacro( "SegDelItem found in defined length Sequence. Skipping" );
141 assert( item.GetVL() == 0 );
142 assert( item.GetNestedDataSet().Size() == 0 );
143 // we need to pay attention that the length of the Sequence of Items will be wrong
144 // this way. Indeed by not adding this item we are changing the size of this sqi
145 }
146 else // Not a seq del item marker
147 #endif
148 {
149 // By design we never load them. If we were to load those attribute
150 // as normal item it would become very complex to convert a sequence
151 // from defined length to undefined length with the risk to write two
152 // seq del marker
153 Items.push_back( item );
154 }
155 l += item.template GetLength<TDE>();
156 if( l > SequenceLengthField )
157 {
158 gdcmDebugMacro( "Found: Length of Item larger than expected" )
159 throw "Length of Item larger than expected";
160 }
161 assert( l <= SequenceLengthField );
162 #ifdef GDCM_SUPPORT_BROKEN_IMPLEMENTATION
163 // MR_Philips_Intera_No_PrivateSequenceImplicitVR.dcm
164 // (0x2005, 0x1080): for some reason computation of length fails...
165 if( SequenceLengthField == 778 && l == 774 )
166 {
167 gdcmWarningMacro( "PMS: Super bad hack" );
168 SequenceLengthField = l;
169 throw Exception( "Wrong Length" );
170 //l = SequenceLengthField;
171 }
172 // Bug_Philips_ItemTag_3F3F
173 // (0x2005, 0x1080): Because we do not handle fully the bug at the item
174 // level we need to check here too
175 else if ( SequenceLengthField == 444 && l == 3*71 )
176 {
177 // This one is a double bug. Item length is wrong and impact SQ length
178 gdcmWarningMacro( "PMS: Super bad hack" );
179 l = SequenceLengthField;
180 }
181 #endif
182 }
183 assert( l == SequenceLengthField );
184 }
185 return is;
186 }
187
188 template <typename TDE,typename TSwap>
189 std::ostream const &Write(std::ostream &os) const
190 {
191 typename ItemVector::const_iterator it = Items.begin();
192 for(;it != Items.end(); ++it)
193 {
194 it->Write<TDE,TSwap>(os);
195 }
196 if( SequenceLengthField.IsUndefined() )
197 {
198 // seq del item is not stored, write it !
199 const Tag seqDelItem(0xfffe,0xe0dd);
200 seqDelItem.Write<TSwap>(os);
201 VL zero = 0;
202 zero.Write<TSwap>(os);
203 }
204
205 return os;
206 }
207
208 //protected:
209 void Print(std::ostream &os) const {
210 os << "\t(" << SequenceLengthField << ")\n";
211 ItemVector::const_iterator it =
212 Items.begin();
213 for(;it != Items.end(); ++it)
214 {
215 os << " " << *it;
216 }
217 if( SequenceLengthField.IsUndefined() )
218 {
219 const Tag seqDelItem(0xfffe,0xe0dd);
220 VL zero = 0;
221 os << seqDelItem;
222 os << "\t" << zero;
223 }
224 }
225
226 static SmartPointer<SequenceOfItems> New()
227 {
228 return new SequenceOfItems;
229 }
230 bool FindDataElement(const Tag &t) const;
231
232 bool operator==(const Value &val) const
233 {
234 const SequenceOfItems &sqi = dynamic_cast<const SequenceOfItems&>(val);
235 return SequenceLengthField == sqi.SequenceLengthField &&
236 Items == sqi.Items;
237 }
238
239 private:
240 public:
242 VL SequenceLengthField;
244 ItemVector Items;
245 };
246
247 } // end namespace gdcm
248
249 #include "gdcmSequenceOfItems.txx"
250
251 #endif //GDCMSEQUENCEOFITEMS_H