GDCM 2.0.17

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

Generated on Tue Feb 1 2011 12:30:25 for GDCM by doxygen 1.7.3
SourceForge.net Logo