GDCM 2.0.17
|
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