GDCM 2.2.0

- Main Page
- Related Pages
- Namespaces
- Classes
- Files
- Directories
- Examples

- File List
- File Members

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