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

Generated on Sat Dec 4 2010 08:58:43 for GDCM by doxygen 1.7.2
SourceForge.net Logo