GDCM 2.2.0

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

- File List
- File Members

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