GDCM 2.0.17
|
00001 /*========================================================================= 00002 00003 Program: GDCM (Grassroots DICOM). A DICOM library 00004 Module: $URL$ 00005 00006 Copyright (c) 2006-2010 Mathieu Malaterre 00007 All rights reserved. 00008 See Copyright.txt or http://gdcm.sourceforge.net/Copyright.html for details. 00009 00010 This software is distributed WITHOUT ANY WARRANTY; without even 00011 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 00012 PURPOSE. See the above copyright notice for more information. 00013 00014 =========================================================================*/ 00015 00016 #ifndef GDCMSEQUENCEOFITEMS_H 00017 #define GDCMSEQUENCEOFITEMS_H 00018 00019 #include "gdcmValue.h" 00020 #include "gdcmItem.h" 00021 00022 #include <vector> 00023 00024 namespace gdcm 00025 { 00026 00039 class GDCM_EXPORT SequenceOfItems : public Value 00040 { 00041 public: 00042 // Typdefs: 00043 typedef std::vector< Item > ItemVector; 00044 typedef ItemVector::size_type SizeType; 00045 typedef ItemVector::iterator Iterator; 00046 typedef ItemVector::const_iterator ConstIterator; 00047 Iterator Begin() { return Items.begin(); } 00048 Iterator End() { return Items.end(); } 00049 ConstIterator Begin() const { return Items.begin(); } 00050 ConstIterator End() const { return Items.end(); } 00051 00053 SequenceOfItems():SequenceLengthField(0xFFFFFFFF) { } 00054 //SequenceOfItems(VL const &vl = 0xFFFFFFFF):SequenceLengthField(vl),NType(type) { } 00055 00057 VL GetLength() const { return SequenceLengthField; } 00059 void SetLength(VL length) { 00060 SequenceLengthField = length; 00061 } 00062 void SetLengthToUndefined() { 00063 SequenceLengthField = 0xFFFFFFFF; 00064 } 00066 bool IsUndefinedLength() const { 00067 return SequenceLengthField.IsUndefined(); 00068 } 00069 00070 template <typename TDE> 00071 VL ComputeLength() const; 00072 void Clear() {} 00073 00075 void AddItem(Item const &item); 00076 00077 SizeType GetNumberOfItems() const { return Items.size(); } 00078 void SetNumberOfItems(SizeType n) { Items.resize(n); } 00079 00080 /* WARNING: first item is #1 (see DICOM standard) 00081 * Each Item shall be implicitly assigned an ordinal position starting with the value 1 for the 00082 * first Item in the Sequence, and incremented by 1 with each subsequent Item. The last Item in the 00083 * Sequence shall have an ordinal position equal to the number of Items in the Sequence. 00084 */ 00085 const Item &GetItem(SizeType position) const; 00086 Item &GetItem(SizeType position); 00087 00088 SequenceOfItems &operator=(const SequenceOfItems &val) { 00089 SequenceLengthField = val.SequenceLengthField; 00090 Items = val.Items; 00091 return *this; 00092 } 00093 00094 template <typename TDE, typename TSwap> 00095 std::istream &Read(std::istream &is) 00096 { 00097 const Tag seqDelItem(0xfffe,0xe0dd); 00098 if( SequenceLengthField.IsUndefined() ) 00099 { 00100 Item item; 00101 while( item.Read<TDE,TSwap>(is) && item.GetTag() != seqDelItem ) 00102 { 00103 //gdcmDebugMacro( "Item: " << item ); 00104 assert( item.GetTag() != seqDelItem ); 00105 Items.push_back( item ); 00106 item.Clear(); 00107 } 00108 //assert( item.GetTag() == seqDelItem && item.GetVL() == 0 ); 00109 } 00110 else 00111 { 00112 Item item; 00113 VL l = 0; 00114 //is.seekg( SequenceLengthField, std::ios::cur ); return is; 00115 while( l != SequenceLengthField ) 00116 { 00117 try 00118 { 00119 item.Read<TDE,TSwap>(is); 00120 } 00121 catch( Exception &ex ) 00122 { 00123 if( strcmp( ex.GetDescription(), "Changed Length" ) == 0 ) 00124 { 00125 VL newlength = l + item.template GetLength<TDE>(); 00126 if( newlength > SequenceLengthField ) 00127 { 00128 // BogugsItemAndSequenceLength.dcm 00129 gdcmWarningMacro( "SQ length is wrong" ); 00130 SequenceLengthField = newlength; 00131 } 00132 } 00133 else 00134 { 00135 throw ex; 00136 } 00137 } 00138 if( item.GetTag() == seqDelItem ) 00139 { 00140 gdcmWarningMacro( "SegDelItem found in defined length Sequence" ); 00141 } 00142 //assert( item.GetTag() == Tag(0xfffe,0xe000) ); 00143 Items.push_back( item ); 00144 l += item.template GetLength<TDE>(); 00145 if( l > SequenceLengthField ) throw "Length of Item larger than expected"; 00146 assert( l <= SequenceLengthField ); 00147 #ifdef GDCM_SUPPORT_BROKEN_IMPLEMENTATION 00148 // MR_Philips_Intera_No_PrivateSequenceImplicitVR.dcm 00149 // (0x2005, 0x1080): for some reason computation of length fails... 00150 if( SequenceLengthField == 778 && l == 774 ) 00151 { 00152 gdcmWarningMacro( "PMS: Super bad hack" ); 00153 SequenceLengthField = l; 00154 throw Exception( "Wrong Length" ); 00155 //l = SequenceLengthField; 00156 } 00157 // Bug_Philips_ItemTag_3F3F 00158 // (0x2005, 0x1080): Because we do not handle fully the bug at the item 00159 // level we need to check here too 00160 else if ( SequenceLengthField == 444 && l == 3*71 ) 00161 { 00162 // This one is a double bug. Item length is wrong and impact SQ length 00163 gdcmWarningMacro( "PMS: Super bad hack" ); 00164 l = SequenceLengthField; 00165 } 00166 #endif 00167 } 00168 assert( l == SequenceLengthField ); 00169 } 00170 return is; 00171 } 00172 00173 template <typename TDE,typename TSwap> 00174 std::ostream const &Write(std::ostream &os) const 00175 { 00176 typename ItemVector::const_iterator it = Items.begin(); 00177 for(;it != Items.end(); ++it) 00178 { 00179 it->Write<TDE,TSwap>(os); 00180 } 00181 if( SequenceLengthField.IsUndefined() ) 00182 { 00183 // seq del item is not stored, write it ! 00184 const Tag seqDelItem(0xfffe,0xe0dd); 00185 seqDelItem.Write<TSwap>(os); 00186 VL zero = 0; 00187 zero.Write<TSwap>(os); 00188 } 00189 00190 return os; 00191 } 00192 00193 //protected: 00194 void Print(std::ostream &os) const { 00195 os << "\t(" << SequenceLengthField << ")\n"; 00196 ItemVector::const_iterator it = 00197 Items.begin(); 00198 for(;it != Items.end(); ++it) 00199 { 00200 os << " " << *it; 00201 } 00202 if( SequenceLengthField.IsUndefined() ) 00203 { 00204 const Tag seqDelItem(0xfffe,0xe0dd); 00205 VL zero = 0; 00206 os << seqDelItem; 00207 os << "\t" << zero; 00208 } 00209 } 00210 00211 static SmartPointer<SequenceOfItems> New() 00212 { 00213 return new SequenceOfItems; 00214 } 00215 bool FindDataElement(const Tag &t) const; 00216 00217 bool operator==(const Value &val) const 00218 { 00219 const SequenceOfItems &sqi = dynamic_cast<const SequenceOfItems&>(val); 00220 return SequenceLengthField == sqi.SequenceLengthField && 00221 Items == sqi.Items; 00222 } 00223 00224 private: 00225 public: 00227 VL SequenceLengthField; 00229 ItemVector Items; 00230 }; 00231 00232 } // end namespace gdcm 00233 00234 #include "gdcmSequenceOfItems.txx" 00235 00236 #endif //GDCMSEQUENCEOFITEMS_H