GDCM  2.2.0
gdcmSequenceOfFragments.h
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: GDCM (Grassroots DICOM). A DICOM library
4 
5  Copyright (c) 2006-2011 Mathieu Malaterre
6  All rights reserved.
7  See Copyright.txt or http://gdcm.sourceforge.net/Copyright.html for details.
8 
9  This software is distributed WITHOUT ANY WARRANTY; without even
10  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11  PURPOSE. See the above copyright notice for more information.
12 
13 =========================================================================*/
14 #ifndef GDCMSEQUENCEOFFRAGMENTS_H
15 #define GDCMSEQUENCEOFFRAGMENTS_H
16 
17 #include "gdcmValue.h"
18 #include "gdcmVL.h"
19 #include "gdcmFragment.h"
20 #include "gdcmBasicOffsetTable.h"
21 
22 namespace gdcm
23 {
24 
25  // FIXME gdcmSequenceOfItems and gdcmSequenceOfFragments
26  // should be rethink (duplicate code)
32 {
33 public:
34  // Typdefs:
35  typedef std::vector<Fragment> FragmentVector;
36  typedef FragmentVector::size_type SizeType;
37  typedef FragmentVector::iterator Iterator;
38  typedef FragmentVector::const_iterator ConstIterator;
39  Iterator Begin() { return Fragments.begin(); }
40  Iterator End() { return Fragments.end(); }
41  ConstIterator Begin() const { return Fragments.begin(); }
42  ConstIterator End() const { return Fragments.end(); }
43 
45  SequenceOfFragments():Table(),SequenceLengthField(0xFFFFFFFF) { }
46 
48  VL GetLength() const {
49  return SequenceLengthField;
50  }
51 
53  void SetLength(VL length) {
54  SequenceLengthField = length;
55  }
56 
58  void Clear();
59 
61  void AddFragment(Fragment const &item);
62 
63  // Compute the length of all fragments (and framents only!).
64  // Basically the size of the PixelData as stored (in bytes).
65  unsigned long ComputeByteLength() const;
66 
67  // Compute the length of fragments (in bytes)+ length of tag...
68  // to be used for computation of Group Length
69  VL ComputeLength() const;
70 
71  // Get the buffer
72  bool GetBuffer(char *buffer, unsigned long length) const;
73  bool GetFragBuffer(unsigned int fragNb, char *buffer, unsigned long &length) const;
74 
75  SizeType GetNumberOfFragments() const;
76  const Fragment& GetFragment(SizeType num) const;
77 
78  // Write the buffer of each fragment (call WriteBuffer on all Fragments, which are
79  // ByteValue). No Table information is written.
80  bool WriteBuffer(std::ostream &os) const;
81 
82  const BasicOffsetTable &GetTable() const { return Table; }
84 
85 
86 template <typename TSwap>
87 std::istream& Read(std::istream &is)
88 {
89  assert( SequenceLengthField.IsUndefined() );
90  //if( SequenceLengthField.IsUndefined() )
91  {
92  const Tag seqDelItem(0xfffe,0xe0dd);
93  // First item is the basic offset table:
94  try
95  {
96  Table.Read<TSwap>(is);
97  gdcmDebugMacro( "Table: " << Table );
98  }
99  catch(...)
100  {
101  // Bug_Siemens_PrivateIconNoItem.dcm
102  // First thing first let's rewind
103  is.seekg(-4, std::ios::cur);
104  if ( Table.GetTag() == Tag(0xd8ff,0xe0ff) )
105  {
106  Fragment frag;
107  is.seekg( 8340, std::ios::cur );
108  char dummy[8340];
109  frag.SetByteValue( dummy, 8340 - Table.GetLength() - 16 );
110  Fragments.push_back( frag );
111  return is;
112  }
113  else
114  {
115  throw "Catch me if you can";
116  //assert(0);
117  }
118  }
119  // not used for now...
120  Fragment frag;
121  try
122  {
123  while( frag.Read<TSwap>(is) && frag.GetTag() != seqDelItem )
124  {
125  gdcmDebugMacro( "Frag: " << frag );
126  Fragments.push_back( frag );
127  }
128  assert( frag.GetTag() == seqDelItem && frag.GetVL() == 0 );
129  }
130  catch(Exception &ex)
131  {
132  (void)ex; //to avoid unreferenced variable warning on release
133 #ifdef GDCM_SUPPORT_BROKEN_IMPLEMENTATION
134  // that's ok ! In all cases the whole file was read, because
135  // Fragment::Read only fail on eof() reached 1.
136  // SIEMENS-JPEG-CorruptFrag.dcm is more difficult to deal with, we have a
137  // partial fragment, read we decide to add it anyway to the stack of
138  // fragments (eof was reached so we need to clear error bit)
139  if( frag.GetTag() == Tag(0xfffe,0xe000) )
140  {
141  gdcmWarningMacro( "Pixel Data Fragment could be corrupted. Use file at own risk" );
142  Fragments.push_back( frag );
143  is.clear(); // clear the error bit
144  }
145  // 2. GENESIS_SIGNA-JPEG-CorruptFrag.dcm
146  else if ( frag.GetTag() == Tag(0xddff,0x00e0) )
147  {
148  assert( Fragments.size() == 1 );
149  const ByteValue *bv = Fragments[0].GetByteValue();
150  assert( (unsigned char)bv->GetPointer()[ bv->GetLength() - 1 ] == 0xfe );
151  // Yes this is an extra copy, this is a bug anyway, go fix YOUR code
152  Fragments[0].SetByteValue( bv->GetPointer(), bv->GetLength() - 1 );
153  gdcmWarningMacro( "JPEG Fragment length was declared with an extra byte"
154  " at the end: stripped !" );
155  is.clear(); // clear the error bit
156  }
157  else
158  {
159  // 3. gdcm-JPEG-LossLess3a.dcm: easy case, an extra tag was found
160  // instead of terminator (eof is the next char)
161  gdcmWarningMacro( "Reading failed at Tag:" << frag.GetTag() <<
162  ". Use file at own risk." << ex.what() );
163  }
164 #else
165  (void)ex;
166 #endif /* GDCM_SUPPORT_BROKEN_IMPLEMENTATION */
167  }
168  }
169 
170  return is;
171 }
172 
173 template <typename TSwap>
174 std::ostream const &Write(std::ostream &os) const
175 {
176  if( !Table.Write<TSwap>(os) )
177  {
178  assert(0 && "Should not happen");
179  return os;
180  }
181  for(ConstIterator it = Begin();it != End(); ++it)
182  {
183  it->Write<TSwap>(os);
184  }
185  // seq del item is not stored, write it !
186  const Tag seqDelItem(0xfffe,0xe0dd);
187  seqDelItem.Write<TSwap>(os);
188  VL zero = 0;
189  zero.Write<TSwap>(os);
190 
191  return os;
192 }
193 
194 //#if defined(SWIGPYTHON) || defined(SWIGCSHARP) || defined(SWIGJAVA)
195  // For now leave it there, this does not make sense in the C++ layer
196  // Create a new object
198  {
199  return new SequenceOfFragments();
200  }
201 //#endif
202 
203 protected:
204 public:
205  void Print(std::ostream &os) const {
206  os << "SQ L= " << SequenceLengthField << "\n";
207  os << "Table:" << Table << "\n";
208  for(ConstIterator it = Begin();it != End(); ++it)
209  {
210  os << " " << *it << "\n";
211  }
212  assert( SequenceLengthField.IsUndefined() );
213  {
214  const Tag seqDelItem(0xfffe,0xe0dd);
215  VL zero = 0;
216  os << seqDelItem;
217  os << "\t" << zero;
218  }
219  }
220  bool operator==(const Value &val) const
221  {
222  const SequenceOfFragments &sqf = dynamic_cast<const SequenceOfFragments&>(val);
223  return Table == sqf.Table &&
224  SequenceLengthField == sqf.SequenceLengthField &&
225  Fragments == sqf.Fragments;
226  }
227 
228 private:
230  VL SequenceLengthField;
232  FragmentVector Fragments;
233 };
234 
240 } // end namespace gdcm
241 
242 #endif //GDCMSEQUENCEOFFRAGMENTS_H

Generated on Wed Jun 13 2012 20:40:37 for GDCM by doxygen 1.8.1
SourceForge.net Logo