GDCM  2.2.0
gdcmFragment.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 #ifndef GDCMFRAGMENT_H
00015 #define GDCMFRAGMENT_H
00016 
00017 #include "gdcmDataElement.h"
00018 #include "gdcmByteValue.h"
00019 #include "gdcmSmartPointer.h"
00020 #include "gdcmParseException.h"
00021 
00022 namespace gdcm
00023 {
00024 
00025 // Implementation detail:
00026 // I think Fragment should be a protected sublclass of DataElement:
00027 // looking somewhat like this:
00028 /*
00029 class GDCM_EXPORT Fragment : protected DataElement
00030 {
00031 public:
00032   using DataElement::GetTag;
00033   using DataElement::GetVL;
00034   using DataElement::SetByteValue;
00035   using DataElement::GetByteValue;
00036   using DataElement::GetValue;
00037 */
00038 // Instead I am only hiding the SetTag member...
00039 
00043 class GDCM_EXPORT Fragment : public DataElement
00044 {
00045 //protected:
00046 //  void SetTag(const Tag &t);
00047 public:
00048   Fragment() : DataElement(Tag(0xfffe, 0xe000), 0) {}
00049   friend std::ostream &operator<<(std::ostream &os, const Fragment &val);
00050 
00051   VL GetLength() const {
00052     assert( !ValueLengthField.IsUndefined() );
00053     assert( !ValueField || ValueField->GetLength() == ValueLengthField );
00054     return TagField.GetLength() + ValueLengthField.GetLength()
00055       + ValueLengthField;
00056   }
00057 
00058   template <typename TSwap>
00059   std::istream &Read(std::istream &is)
00060     {
00061     TagField.Read<TSwap>(is);
00062     return ReadValue<TSwap>(is);
00063     }
00064 
00065   template <typename TSwap>
00066   std::istream &ReadValue(std::istream &is)
00067     {
00068     // Superclass
00069     const Tag itemStart(0xfffe, 0xe000);
00070     const Tag seqDelItem(0xfffe,0xe0dd);
00071     if( !is )
00072       {
00073       //  BogusItemStartItemEnd.dcm
00074       throw Exception( "Problem" );
00075       return is;
00076       }
00077     if( !ValueLengthField.Read<TSwap>(is) )
00078       {
00079       // GENESIS_SIGNA-JPEG-CorruptFrag.dcm
00080       // JPEG fragment is declared to have 61902, but infact really is only 61901
00081       // so we end up reading 0xddff,0x00e0, and VL = 0x0 (1 byte)
00082       throw Exception( "Problem" );
00083       return is;
00084       }
00085 #ifdef GDCM_SUPPORT_BROKEN_IMPLEMENTATION
00086     if( TagField != itemStart && TagField != seqDelItem )
00087       {
00088       throw Exception( "Problem" );
00089       }
00090 #endif
00091     // Self
00092     SmartPointer<ByteValue> bv = new ByteValue;
00093     bv->SetLength(ValueLengthField);
00094     if( !bv->Read<TSwap>(is) )
00095       {
00096       // Fragment is incomplete, but is a itemStart, let's try to push it anyway...
00097       gdcmWarningMacro( "Fragment could not be read" );
00098       //bv->SetLength(is.gcount());
00099       ValueField = bv;
00100       ParseException pe;
00101       pe.SetLastElement( *this );
00102       throw pe;
00103       return is;
00104       }
00105     ValueField = bv;
00106     return is;
00107     }
00108 
00109 
00110   template <typename TSwap>
00111   std::ostream &Write(std::ostream &os) const {
00112     const Tag itemStart(0xfffe, 0xe000);
00113     const Tag seqDelItem(0xfffe,0xe0dd);
00114     if( !TagField.Write<TSwap>(os) )
00115       {
00116       assert(0 && "Should not happen");
00117       return os;
00118       }
00119     assert( TagField == itemStart
00120          || TagField == seqDelItem );
00121     const ByteValue *bv = GetByteValue();
00122     // VL
00123     // The following piece of code is hard to read in order to support such broken file as:
00124     // CompressedLossy.dcm
00125     if( IsEmpty() )
00126       {
00127       //assert( bv );
00128       VL zero = 0;
00129       if( !zero.Write<TSwap>(os) )
00130         {
00131         assert(0 && "Should not happen");
00132         return os;
00133         }
00134       }
00135     else
00136       {
00137       assert( ValueLengthField );
00138       if( !ValueLengthField.Write<TSwap>(os) )
00139         {
00140         assert(0 && "Should not happen");
00141         return os;
00142         }
00143       }
00144     // Value
00145     if( ValueLengthField && bv )
00146       {
00147       // Self
00148       assert( bv );
00149       assert( bv->GetLength() == ValueLengthField );
00150       if( !bv->Write<TSwap>(os) )
00151         {
00152         assert(0 && "Should not happen");
00153         return os;
00154         }
00155       }
00156     return os;
00157     }
00158 };
00159 //-----------------------------------------------------------------------------
00160 inline std::ostream &operator<<(std::ostream &os, const Fragment &val)
00161 {
00162   os << "Tag: " << val.TagField;
00163   os << "\tVL: " << val.ValueLengthField;
00164   if( val.ValueField )
00165     {
00166     os << "\t" << *(val.ValueField);
00167     }
00168 
00169   return os;
00170 }
00171 
00172 } // end namespace gdcm
00173 
00174 #endif //GDCMFRAGMENT_H

Generated on Sun Jun 3 2012 15:26:48 for GDCM by doxygen 1.8.0
SourceForge.net Logo