GDCM  2.2.6
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 #ifdef GDCM_SUPPORT_BROKEN_IMPLEMENTATION
164  // MR_Philips_Intera_No_PrivateSequenceImplicitVR.dcm
165  // (0x2005, 0x1080): for some reason computation of length fails...
166  if( SequenceLengthField == 778 && l == 774 )
167  {
168  gdcmWarningMacro( "PMS: Super bad hack" );
169  SequenceLengthField = l;
170  throw Exception( "Wrong Length" );
171  //l = SequenceLengthField;
172  }
173  // Bug_Philips_ItemTag_3F3F
174  // (0x2005, 0x1080): Because we do not handle fully the bug at the item
175  // level we need to check here too
176  else if ( SequenceLengthField == 444 && l == 3*71 )
177  {
178  // This one is a double bug. Item length is wrong and impact SQ length
179  gdcmWarningMacro( "PMS: Super bad hack" );
180  l = SequenceLengthField;
181  }
182 #endif
183  }
184  assert( l == SequenceLengthField );
185  }
186  return is;
187  }
188 
189  template <typename TDE,typename TSwap>
190  std::ostream const &Write(std::ostream &os) const
191  {
192  typename ItemVector::const_iterator it = Items.begin();
193  for(;it != Items.end(); ++it)
194  {
195  it->Write<TDE,TSwap>(os);
196  }
197  if( SequenceLengthField.IsUndefined() )
198  {
199  // seq del item is not stored, write it !
200  const Tag seqDelItem(0xfffe,0xe0dd);
201  seqDelItem.Write<TSwap>(os);
202  VL zero = 0;
203  zero.Write<TSwap>(os);
204  }
205 
206  return os;
207  }
208 
209 //protected:
210  void Print(std::ostream &os) const {
211  os << "\t(" << SequenceLengthField << ")\n";
212  ItemVector::const_iterator it =
213  Items.begin();
214  for(;it != Items.end(); ++it)
215  {
216  os << " " << *it;
217  }
218  if( SequenceLengthField.IsUndefined() )
219  {
220  const Tag seqDelItem(0xfffe,0xe0dd);
221  VL zero = 0;
222  os << seqDelItem;
223  os << "\t" << zero;
224  }
225  }
226 
228  {
229  return new SequenceOfItems;
230  }
231  bool FindDataElement(const Tag &t) const;
232 
233  bool operator==(const Value &val) const
234  {
235  const SequenceOfItems &sqi = dynamic_cast<const SequenceOfItems&>(val);
236  return SequenceLengthField == sqi.SequenceLengthField &&
237  Items == sqi.Items;
238  }
239 
240 private:
241 public:
246 };
247 
248 } // end namespace gdcm
249 
250 #include "gdcmSequenceOfItems.txx"
251 
252 #endif //GDCMSEQUENCEOFITEMS_H
ItemVector::iterator Iterator
Definition: gdcmSequenceOfItems.h:45
Class to represent a Sequence Of Items (value representation : SQ)
Definition: gdcmSequenceOfItems.h:39
void Print(std::ostream &os) const
Definition: gdcmSequenceOfItems.h:210
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:190
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:245
#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:227
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:233
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:243
bool IsUndefinedLength() const
return if Value Length if of undefined length
Definition: gdcmSequenceOfItems.h:65
std::istream & Read(std::istream &is, bool readvalues=true)
Definition: gdcmSequenceOfItems.h:94
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 Sat Dec 21 2013 05:56:17 for GDCM by doxygen 1.8.5
SourceForge.net Logo