# gdcmSequenceOfItems.h

Go to the documentation of this file.

    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