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     ReadPreValue<TSwap>(is);
00062     return ReadValue<TSwap>(is);
00063     }
00064 
00065   template <typename TSwap>
00066   std::istream &ReadPreValue(std::istream &is)
00067     {
00068     const Tag itemStart(0xfffe, 0xe000);
00069     const Tag seqDelItem(0xfffe,0xe0dd);
00070 
00071     TagField.Read<TSwap>(is);
00072     if( !is )
00073       {
00074       //  BogusItemStartItemEnd.dcm
00075       throw Exception( "Problem" );
00076       return is;
00077       }
00078     if( !ValueLengthField.Read<TSwap>(is) )
00079       {
00080       // GENESIS_SIGNA-JPEG-CorruptFrag.dcm
00081       // JPEG fragment is declared to have 61902, but infact really is only 61901
00082       // so we end up reading 0xddff,0x00e0, and VL = 0x0 (1 byte)
00083       throw Exception( "Problem" );
00084       return is;
00085       }
00086 #ifdef GDCM_SUPPORT_BROKEN_IMPLEMENTATION
00087     if( TagField != itemStart && TagField != seqDelItem )
00088       {
00089       throw Exception( "Problem" );
00090       }
00091 #endif
00092     return is;
00093     }
00094 
00095   template <typename TSwap>
00096   std::istream &ReadValue(std::istream &is)
00097     {
00098     // Superclass
00099     const Tag itemStart(0xfffe, 0xe000);
00100     const Tag seqDelItem(0xfffe,0xe0dd);
00101     // Self
00102     SmartPointer<ByteValue> bv = new ByteValue;
00103     bv->SetLength(ValueLengthField);
00104     if( !bv->Read<TSwap>(is) )
00105       {
00106       // Fragment is incomplete, but is a itemStart, let's try to push it anyway...
00107       gdcmWarningMacro( "Fragment could not be read" );
00108       //bv->SetLength(is.gcount());
00109       ValueField = bv;
00110       ParseException pe;
00111       pe.SetLastElement( *this );
00112       throw pe;
00113       return is;
00114       }
00115     ValueField = bv;
00116     return is;
00117     }
00118 
00119 
00120   template <typename TSwap>
00121   std::ostream &Write(std::ostream &os) const {
00122     const Tag itemStart(0xfffe, 0xe000);
00123     const Tag seqDelItem(0xfffe,0xe0dd);
00124     if( !TagField.Write<TSwap>(os) )
00125       {
00126       assert(0 && "Should not happen");
00127       return os;
00128       }
00129     assert( TagField == itemStart
00130          || TagField == seqDelItem );
00131     const ByteValue *bv = GetByteValue();
00132     // VL
00133     // The following piece of code is hard to read in order to support such broken file as:
00134     // CompressedLossy.dcm
00135     if( IsEmpty() )
00136       {
00137       //assert( bv );
00138       VL zero = 0;
00139       if( !zero.Write<TSwap>(os) )
00140         {
00141         assert(0 && "Should not happen");
00142         return os;
00143         }
00144       }
00145     else
00146       {
00147       assert( ValueLengthField );
00148       if( !ValueLengthField.Write<TSwap>(os) )
00149         {
00150         assert(0 && "Should not happen");
00151         return os;
00152         }
00153       }
00154     // Value
00155     if( ValueLengthField && bv )
00156       {
00157       // Self
00158       assert( bv );
00159       assert( bv->GetLength() == ValueLengthField );
00160       if( !bv->Write<TSwap>(os) )
00161         {
00162         assert(0 && "Should not happen");
00163         return os;
00164         }
00165       }
00166     return os;
00167     }
00168 };
00169 //-----------------------------------------------------------------------------
00170 inline std::ostream &operator<<(std::ostream &os, const Fragment &val)
00171 {
00172   os << "Tag: " << val.TagField;
00173   os << "\tVL: " << val.ValueLengthField;
00174   if( val.ValueField )
00175     {
00176     os << "\t" << *(val.ValueField);
00177     }
00178 
00179   return os;
00180 }
00181 
00182 } // end namespace gdcm
00183 
00184 #endif //GDCMFRAGMENT_H

Generated on Mon Feb 4 2013 03:54:54 for GDCM by doxygen 1.7.1
SourceForge.net Logo