# 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-2009 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::iterator Iterator;
    00045   typedef ItemVector::const_iterator ConstIterator;
    00046   Iterator Begin() { return Items.begin(); }
    00047   Iterator End() { return Items.end(); }
    00048   ConstIterator Begin() const { return Items.begin(); }
    00049   ConstIterator End() const { return Items.end(); }
    00050
    00052   SequenceOfItems():SequenceLengthField(0xFFFFFFFF) { }
    00053   //SequenceOfItems(VL const &vl = 0xFFFFFFFF):SequenceLengthField(vl),NType(type) { }
    00054
    00056   VL GetLength() const { return SequenceLengthField; }
    00058   void SetLength(VL length) {
    00059     SequenceLengthField = length;
    00060   }
    00061   void SetLengthToUndefined() {
    00062     SequenceLengthField = 0xFFFFFFFF;
    00063   }
    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   unsigned int GetNumberOfItems() const {  return Items.size(); }
    00077   void SetNumberOfItems(unsigned int 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(unsigned int position) const;
    00085   Item &GetItem(unsigned int 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         if( item.GetTag() == seqDelItem )
    00138           {
    00139           gdcmWarningMacro( "SegDelItem found in defined length Sequence" );
    00140           }
    00141         //assert( item.GetTag() == Tag(0xfffe,0xe000) );
    00142         Items.push_back( item );
    00143         l += item.template GetLength<TDE>();
    00144         if( l > SequenceLengthField ) throw "Length of Item larger than expected";
    00145         assert( l <= SequenceLengthField );
    00146 #ifdef GDCM_SUPPORT_BROKEN_IMPLEMENTATION
    00147         // MR_Philips_Intera_No_PrivateSequenceImplicitVR.dcm
    00148         // (0x2005, 0x1080): for some reason computation of length fails...
    00149         if( SequenceLengthField == 778 && l == 774 )
    00150           {
    00151           gdcmWarningMacro( "PMS: Super bad hack" );
    00152           SequenceLengthField = l;
    00153           throw Exception( "Wrong Length" );
    00154           //l = SequenceLengthField;
    00155           }
    00156         // Bug_Philips_ItemTag_3F3F
    00157         // (0x2005, 0x1080): Because we do not handle fully the bug at the item
    00158         // level we need to check here too
    00159         else if ( SequenceLengthField == 444 && l == 3*71 )
    00160           {
    00161           // This one is a double bug. Item length is wrong and impact SQ length
    00162           gdcmWarningMacro( "PMS: Super bad hack" );
    00163           l = SequenceLengthField;
    00164           }
    00165 #endif
    00166         }
    00167       assert( l == SequenceLengthField );
    00168       }
    00169     return is;
    00170     }
    00171
    00172   template <typename TDE,typename TSwap>
    00173   std::ostream const &Write(std::ostream &os) const
    00174     {
    00175     typename ItemVector::const_iterator it = Items.begin();
    00176     for(;it != Items.end(); ++it)
    00177       {
    00178       it->Write<TDE,TSwap>(os);
    00179       }
    00180     if( SequenceLengthField.IsUndefined() )
    00181       {
    00182       // seq del item is not stored, write it !
    00183       const Tag seqDelItem(0xfffe,0xe0dd);
    00184       seqDelItem.Write<TSwap>(os);
    00185       VL zero = 0;
    00186       zero.Write<TSwap>(os);
    00187       }
    00188
    00189     return os;
    00190     }
    00191
    00192 //protected:
    00193   void Print(std::ostream &os) const {
    00194     os << "\t(" << SequenceLengthField << ")\n";
    00195     ItemVector::const_iterator it =
    00196       Items.begin();
    00197     for(;it != Items.end(); ++it)
    00198       {
    00199       os << "  " << *it;
    00200       }
    00201     if( SequenceLengthField.IsUndefined() )
    00202       {
    00203       const Tag seqDelItem(0xfffe,0xe0dd);
    00204       VL zero = 0;
    00205       os << seqDelItem;
    00206       os << "\t" << zero;
    00207       }
    00208   }
    00209
    00210   static SmartPointer<SequenceOfItems> New()
    00211   {
    00212      return new SequenceOfItems;
    00213   }
    00214   bool FindDataElement(const Tag &t) const;
    00215
    00216 private:
    00217 public:
    00219   VL SequenceLengthField;
    00221   ItemVector Items;
    00222 };
    00223
    00224 } // end namespace gdcm
    00225
    00226 #include "gdcmSequenceOfItems.txx"
    00227
    00228 #endif //__gdcmSequenceOfItems_h
    00229