GDCM 2.0.17

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

Generated on Wed Feb 2 2011 19:21:02 for GDCM by doxygen 1.7.3
SourceForge.net Logo