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

Generated on Thu Oct 17 2013 10:05:56 for GDCM by doxygen 1.8.4
SourceForge.net Logo