GDCM  2.2.0
gdcmSequenceOfItems.h
Go to the documentation of this file.
00001 /*=========================================================================
00002 
00003   Program: GDCM (Grassroots DICOM). A DICOM library
00004 
00005   Copyright (c) 2006-2011 Mathieu Malaterre
00006   All rights reserved.
00007   See Copyright.txt or http://gdcm.sourceforge.net/Copyright.html for details.
00008 
00009      This software is distributed WITHOUT ANY WARRANTY; without even
00010      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
00011      PURPOSE.  See the above copyright notice for more information.
00012 
00013 =========================================================================*/
00014 
00015 #ifndef GDCMSEQUENCEOFITEMS_H
00016 #define GDCMSEQUENCEOFITEMS_H
00017 
00018 #include "gdcmValue.h"
00019 #include "gdcmItem.h"
00020 
00021 #include <vector>
00022 #include <cstring> // strcmp
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   }
00063   void SetLengthToUndefined();
00065   bool IsUndefinedLength() const {
00066     return SequenceLengthField.IsUndefined();
00067   }
00068 
00069   template <typename TDE>
00070   VL ComputeLength() const;
00071   void Clear() {}
00072 
00074   void AddItem(Item const &item);
00075 
00076   SizeType GetNumberOfItems() const {  return Items.size(); }
00077   void SetNumberOfItems(SizeType n) {  Items.resize(n); }
00078 
00079   /* WARNING: first item is #1 (see DICOM standard)
00080    *  Each Item shall be implicitly assigned an ordinal position starting with the value 1 for the
00081    * first Item in the Sequence, and incremented by 1 with each subsequent Item. The last Item in the
00082    * Sequence shall have an ordinal position equal to the number of Items in the Sequence.
00083    */
00084   const Item &GetItem(SizeType position) const;
00085   Item &GetItem(SizeType position);
00086 
00087   SequenceOfItems &operator=(const SequenceOfItems &val) {
00088     SequenceLengthField = val.SequenceLengthField;
00089     Items = val.Items;
00090     return *this;
00091     }
00092 
00093   template <typename TDE, typename TSwap>
00094   std::istream &Read(std::istream &is)
00095     {
00096     const Tag seqDelItem(0xfffe,0xe0dd);
00097     if( SequenceLengthField.IsUndefined() )
00098       {
00099       Item item;
00100       while( item.Read<TDE,TSwap>(is) && item.GetTag() != seqDelItem )
00101         {
00102         //gdcmDebugMacro( "Item: " << item );
00103         assert( item.GetTag() != seqDelItem );
00104         Items.push_back( item );
00105         item.Clear();
00106         }
00107       //assert( item.GetTag() == seqDelItem && item.GetVL() == 0 );
00108       }
00109     else
00110       {
00111       Item item;
00112       VL l = 0;
00113       //is.seekg( SequenceLengthField, std::ios::cur ); return is;
00114       while( l != SequenceLengthField )
00115         {
00116         try
00117           {
00118           item.Read<TDE,TSwap>(is);
00119           }
00120         catch( Exception &ex )
00121           {
00122           if( strcmp( ex.GetDescription(), "Changed Length" ) == 0 )
00123             {
00124             VL newlength = l + item.template GetLength<TDE>();
00125             if( newlength > SequenceLengthField )
00126               {
00127               // BogugsItemAndSequenceLength.dcm
00128               gdcmWarningMacro( "SQ length is wrong" );
00129               SequenceLengthField = newlength;
00130               }
00131             }
00132           else
00133             {
00134             throw ex;
00135             }
00136           }
00137 #ifdef GDCM_SUPPORT_BROKEN_IMPLEMENTATION
00138         if( item.GetTag() == seqDelItem )
00139           {
00140           gdcmWarningMacro( "SegDelItem found in defined length Sequence. Skipping" );
00141           assert( item.GetVL() == 0 );
00142           assert( item.GetNestedDataSet().Size() == 0 );
00143           // we need to pay attention that the length of the Sequence of Items will be wrong
00144           // this way. Indeed by not adding this item we are changing the size of this sqi
00145           }
00146         else // Not a seq del item marker
00147 #endif
00148           {
00149           // By design we never load them. If we were to load those attribute
00150           // as normal item it would become very complex to convert a sequence
00151           // from defined length to undefined length with the risk to write two
00152           // seq del marker
00153           Items.push_back( item );
00154           }
00155         l += item.template GetLength<TDE>();
00156         if( l > SequenceLengthField )
00157           {
00158           gdcmDebugMacro( "Found: Length of Item larger than expected" )
00159           throw "Length of Item larger than expected";
00160           }
00161         assert( l <= SequenceLengthField );
00162 #ifdef GDCM_SUPPORT_BROKEN_IMPLEMENTATION
00163         // MR_Philips_Intera_No_PrivateSequenceImplicitVR.dcm
00164         // (0x2005, 0x1080): for some reason computation of length fails...
00165         if( SequenceLengthField == 778 && l == 774 )
00166           {
00167           gdcmWarningMacro( "PMS: Super bad hack" );
00168           SequenceLengthField = l;
00169           throw Exception( "Wrong Length" );
00170           //l = SequenceLengthField;
00171           }
00172         // Bug_Philips_ItemTag_3F3F
00173         // (0x2005, 0x1080): Because we do not handle fully the bug at the item
00174         // level we need to check here too
00175         else if ( SequenceLengthField == 444 && l == 3*71 )
00176           {
00177           // This one is a double bug. Item length is wrong and impact SQ length
00178           gdcmWarningMacro( "PMS: Super bad hack" );
00179           l = SequenceLengthField;
00180           }
00181 #endif
00182         }
00183       assert( l == SequenceLengthField );
00184       }
00185     return is;
00186     }
00187 
00188   template <typename TDE,typename TSwap>
00189   std::ostream const &Write(std::ostream &os) const
00190     {
00191     typename ItemVector::const_iterator it = Items.begin();
00192     for(;it != Items.end(); ++it)
00193       {
00194       it->Write<TDE,TSwap>(os);
00195       }
00196     if( SequenceLengthField.IsUndefined() )
00197       {
00198       // seq del item is not stored, write it !
00199       const Tag seqDelItem(0xfffe,0xe0dd);
00200       seqDelItem.Write<TSwap>(os);
00201       VL zero = 0;
00202       zero.Write<TSwap>(os);
00203       }
00204 
00205     return os;
00206     }
00207 
00208 //protected:
00209   void Print(std::ostream &os) const {
00210     os << "\t(" << SequenceLengthField << ")\n";
00211     ItemVector::const_iterator it =
00212       Items.begin();
00213     for(;it != Items.end(); ++it)
00214       {
00215       os << "  " << *it;
00216       }
00217     if( SequenceLengthField.IsUndefined() )
00218       {
00219       const Tag seqDelItem(0xfffe,0xe0dd);
00220       VL zero = 0;
00221       os << seqDelItem;
00222       os << "\t" << zero;
00223       }
00224   }
00225 
00226   static SmartPointer<SequenceOfItems> New()
00227   {
00228      return new SequenceOfItems;
00229   }
00230   bool FindDataElement(const Tag &t) const;
00231 
00232   bool operator==(const Value &val) const
00233     {
00234     const SequenceOfItems &sqi = dynamic_cast<const SequenceOfItems&>(val);
00235     return SequenceLengthField == sqi.SequenceLengthField &&
00236       Items == sqi.Items;
00237     }
00238 
00239 private:
00240 public:
00242   VL SequenceLengthField;
00244   ItemVector Items;
00245 };
00246 
00247 } // end namespace gdcm
00248 
00249 #include "gdcmSequenceOfItems.txx"
00250 
00251 #endif //GDCMSEQUENCEOFITEMS_H

Generated on Tue Mar 27 2012 18:19:33 for GDCM by doxygen 1.8.0
SourceForge.net Logo