Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef GDCMSEQUENCEOFFRAGMENTS_H
00016 #define GDCMSEQUENCEOFFRAGMENTS_H
00017
00018 #include "gdcmValue.h"
00019 #include "gdcmVL.h"
00020 #include "gdcmFragment.h"
00021 #include "gdcmBasicOffsetTable.h"
00022
00023 namespace gdcm
00024 {
00025
00026
00027
00032 class GDCM_EXPORT SequenceOfFragments : public Value
00033 {
00034 public:
00035
00036 typedef std::vector<Fragment> FragmentVector;
00037
00039 SequenceOfFragments():Table(),SequenceLengthField(0xFFFFFFFF) { }
00040
00042 VL GetLength() const {
00043 return SequenceLengthField; }
00045 void SetLength(VL length) {
00046 SequenceLengthField = length;
00047 }
00048 void Clear();
00049
00051 void AddFragment(Fragment const &item);
00052
00053
00054
00055 unsigned long ComputeByteLength() const;
00056
00057
00058
00059 VL ComputeLength() const;
00060
00061
00062 bool GetBuffer(char *buffer, unsigned long length) const;
00063 bool GetFragBuffer(unsigned int fragNb, char *buffer, unsigned long &length) const;
00064 unsigned int GetNumberOfFragments() const;
00065 const Fragment& GetFragment(unsigned int num) const;
00066
00067
00068
00069 bool WriteBuffer(std::ostream &os) const;
00070
00071 const BasicOffsetTable &GetTable() const { return Table; }
00072 BasicOffsetTable &GetTable() { return Table; }
00073
00074
00075 template <typename TSwap>
00076 std::istream& Read(std::istream &is)
00077 {
00078 assert( SequenceLengthField.IsUndefined() );
00079
00080 {
00081 const Tag seqDelItem(0xfffe,0xe0dd);
00082
00083 try
00084 {
00085 Table.Read<TSwap>(is);
00086 gdcmDebugMacro( "Table: " << Table );
00087 }
00088 catch(...)
00089 {
00090
00091
00092 is.seekg(-4, std::ios::cur);
00093 if ( Table.GetTag() == Tag(0xd8ff,0xe0ff) )
00094 {
00095 Fragment frag;
00096 is.seekg( 8340, std::ios::cur );
00097 char dummy[8340];
00098 frag.SetByteValue( dummy, 8340 - Table.GetLength() - 16 );
00099 Fragments.push_back( frag );
00100 return is;
00101 }
00102 else
00103 {
00104 throw "Catch me if you can";
00105
00106 }
00107 }
00108
00109 Fragment frag;
00110 try
00111 {
00112 while( frag.Read<TSwap>(is) && frag.GetTag() != seqDelItem )
00113 {
00114 gdcmDebugMacro( "Frag: " << frag );
00115 Fragments.push_back( frag );
00116 }
00117 assert( frag.GetTag() == seqDelItem && frag.GetVL() == 0 );
00118 }
00119 catch(Exception &ex)
00120 {
00121 #ifdef GDCM_SUPPORT_BROKEN_IMPLEMENTATION
00122
00123
00124
00125 if( frag.GetTag() == Tag(0xfffe,0xe000) )
00126 {
00127 gdcmWarningMacro( "Pixel Data Fragment could be corrupted. Use file at own risk" );
00128 Fragments.push_back( frag );
00129 is.clear();
00130 }
00131
00132 else if ( frag.GetTag() == Tag(0xddff,0x00e0) )
00133 {
00134 assert( Fragments.size() == 1 );
00135 const ByteValue *bv = Fragments[0].GetByteValue();
00136 assert( (unsigned char)bv->GetPointer()[ bv->GetLength() - 1 ] == 0xfe );
00137
00138 Fragments[0].SetByteValue( bv->GetPointer(), bv->GetLength() - 1 );
00139 gdcmWarningMacro( "JPEG Fragment length was declared with an extra byte at the end: stripped !" );
00140 is.clear();
00141 }
00142 else
00143 {
00144
00145 gdcmWarningMacro( "Reading failed at Tag:" << frag.GetTag() << ". Use file at own risk." << ex.what() );
00146 }
00147 #else
00148 (void)ex;
00149 #endif
00150 }
00151 }
00152
00153 return is;
00154 }
00155
00156 template <typename TSwap>
00157 std::ostream const &Write(std::ostream &os) const
00158 {
00159 if( !Table.Write<TSwap>(os) )
00160 {
00161 assert(0 && "Should not happen");
00162 return os;
00163 }
00164 SequenceOfFragments::FragmentVector::const_iterator it = Fragments.begin();
00165 for(;it != Fragments.end(); ++it)
00166 {
00167 it->Write<TSwap>(os);
00168 }
00169
00170 const Tag seqDelItem(0xfffe,0xe0dd);
00171 seqDelItem.Write<TSwap>(os);
00172 VL zero = 0;
00173 zero.Write<TSwap>(os);
00174
00175 return os;
00176 }
00177
00178
00179
00180
00181 static SmartPointer<SequenceOfFragments> New()
00182 {
00183 return new SequenceOfFragments();
00184 }
00185
00186
00187 protected:
00188 public:
00189 void Print(std::ostream &os) const {
00190 os << "SQ L= " << SequenceLengthField << "\n";
00191 os << "Table:" << Table << "\n";
00192 FragmentVector::const_iterator it =
00193 Fragments.begin();
00194 for(;it != Fragments.end(); ++it)
00195 {
00196 os << " " << *it << "\n";
00197 }
00198 assert( SequenceLengthField.IsUndefined() );
00199 {
00200 const Tag seqDelItem(0xfffe,0xe0dd);
00201 VL zero = 0;
00202 os << seqDelItem;
00203 os << "\t" << zero;
00204 }
00205 }
00206 bool operator==(const Value &val) const
00207 {
00208 const SequenceOfFragments &sqf = dynamic_cast<const SequenceOfFragments&>(val);
00209 return Table == sqf.Table &&
00210 SequenceLengthField == sqf.SequenceLengthField &&
00211 Fragments == sqf.Fragments;
00212 }
00213
00214 private:
00215 public:
00216 BasicOffsetTable Table;
00217 VL SequenceLengthField;
00219 FragmentVector Fragments;
00220 };
00221
00227 }
00228
00229 #endif //GDCMSEQUENCEOFFRAGMENTS_H