GDCM  2.2.4
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
ItemVector::iterator Iterator
Definition: gdcmSequenceOfItems.h:45
Class to represent a Sequence Of Items (value representation : SQ)
Definition: gdcmSequenceOfItems.h:39
std::istream & Read(std::istream &is)
Definition: gdcmSequenceOfItems.h:94
void Print(std::ostream &os) const
Definition: gdcmSequenceOfItems.h:209
void SetLength(VL length)
Sets the actual SQ length.
Definition: gdcmSequenceOfItems.h:59
std::istream & Read(std::istream &is)
Definition: gdcmItem.h:97
Class to represent the value of a Data Element.
Definition: gdcmValue.h:29
ItemVector::const_iterator ConstIterator
Definition: gdcmSequenceOfItems.h:46
std::ostream const & Write(std::ostream &os) const
Definition: gdcmSequenceOfItems.h:189
const VL & GetVL() const
Get VL.
Definition: gdcmDataElement.h:74
ConstIterator End() const
Definition: gdcmSequenceOfItems.h:50
#define GDCM_EXPORT
Definition: gdcmWin32.h:34
SequenceOfItems & operator=(const SequenceOfItems &val)
Definition: gdcmSequenceOfItems.h:87
ItemVector Items
Vector of Sequence Items.
Definition: gdcmSequenceOfItems.h:244
#define gdcmWarningMacro(msg)
Warning.
Definition: gdcmTrace.h:141
Value Length.
Definition: gdcmVL.h:29
#define gdcmDebugMacro(msg)
Debug.
Definition: gdcmTrace.h:119
static SmartPointer< SequenceOfItems > New()
Definition: gdcmSequenceOfItems.h:226
const std::ostream & Write(std::ostream &os) const
Write a tag in binary rep.
Definition: gdcmTag.h:169
Class to represent an Item A component of the value of a Data Element that is of Value Representation...
Definition: gdcmItem.h:45
VL GetLength() const
Returns the SQ length, as read from disk.
Definition: gdcmSequenceOfItems.h:57
Iterator Begin()
Definition: gdcmSequenceOfItems.h:47
ItemVector::size_type SizeType
Definition: gdcmSequenceOfItems.h:44
SizeType Size() const
Definition: gdcmDataSet.h:75
const std::ostream & Write(std::ostream &os) const
Definition: gdcmVL.h:99
void SetNumberOfItems(SizeType n)
Definition: gdcmSequenceOfItems.h:77
Class for Smart Pointer.
Definition: gdcmObject.h:26
bool operator==(const Value &val) const
Definition: gdcmSequenceOfItems.h:232
void Clear()
Definition: gdcmSequenceOfItems.h:71
const char * GetDescription() const
Return the Description.
Definition: gdcmException.h:82
const Tag & GetTag() const
Get Tag.
Definition: gdcmDataElement.h:67
ConstIterator Begin() const
Definition: gdcmSequenceOfItems.h:49
VL SequenceLengthField
Total length of the Sequence (or 0xffffffff) if undefined.
Definition: gdcmSequenceOfItems.h:242
bool IsUndefinedLength() const
return if Value Length if of undefined length
Definition: gdcmSequenceOfItems.h:65
const DataSet & GetNestedDataSet() const
Definition: gdcmItem.h:80
Class to represent a DICOM Data Element (Attribute) Tag (Group, Element). Basically an uint32_t which...
Definition: gdcmTag.h:38
void Clear()
Definition: gdcmItem.h:51
Exception.
Definition: gdcmException.h:33
std::vector< Item > ItemVector
Definition: gdcmSequenceOfItems.h:43
Iterator End()
Definition: gdcmSequenceOfItems.h:48
SequenceOfItems()
constructor (UndefinedLength by default)
Definition: gdcmSequenceOfItems.h:53
SizeType GetNumberOfItems() const
Definition: gdcmSequenceOfItems.h:76

Generated on Wed Feb 19 2014 09:21:07 for GDCM by doxygen 1.8.6
SourceForge.net Logo