GDCM  2.2.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)
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 
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:
245 };
246 
247 } // end namespace gdcm
248 
249 #include "gdcmSequenceOfItems.txx"
250 
251 #endif //GDCMSEQUENCEOFITEMS_H

Generated on Wed Jun 13 2012 20:40:37 for GDCM by doxygen 1.8.1
SourceForge.net Logo