GDCM 2.2.1

- Main Page
- Related Pages
- Namespaces
- Classes
- Files
- Examples

- File List
- File Members

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)
31 class GDCM_EXPORT SequenceOfFragments : public Value
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; }
83 BasicOffsetTable &GetTable() { 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;
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 #endif /* GDCM_SUPPORT_BROKEN_IMPLEMENTATION */
165 }
166 }
167
168 return is;
169 }
170
171 template <typename TSwap>
172 std::ostream const &Write(std::ostream &os) const
173 {
174 if( !Table.Write<TSwap>(os) )
175 {
176 assert(0 && "Should not happen");
177 return os;
178 }
179 for(ConstIterator it = Begin();it != End(); ++it)
180 {
181 it->Write<TSwap>(os);
182 }
183 // seq del item is not stored, write it !
184 const Tag seqDelItem(0xfffe,0xe0dd);
185 seqDelItem.Write<TSwap>(os);
186 VL zero = 0;
187 zero.Write<TSwap>(os);
188
189 return os;
190 }
191
192 //#if defined(SWIGPYTHON) || defined(SWIGCSHARP) || defined(SWIGJAVA)
193 // For now leave it there, this does not make sense in the C++ layer
194 // Create a new object
195 static SmartPointer<SequenceOfFragments> New()
196 {
197 return new SequenceOfFragments();
198 }
199 //#endif
200
201 protected:
202 public:
203 void Print(std::ostream &os) const {
204 os << "SQ L= " << SequenceLengthField << "\n";
205 os << "Table:" << Table << "\n";
206 for(ConstIterator it = Begin();it != End(); ++it)
207 {
208 os << " " << *it << "\n";
209 }
210 assert( SequenceLengthField.IsUndefined() );
211 {
212 const Tag seqDelItem(0xfffe,0xe0dd);
213 VL zero = 0;
214 os << seqDelItem;
215 os << "\t" << zero;
216 }
217 }
218 bool operator==(const Value &val) const
219 {
220 const SequenceOfFragments &sqf = dynamic_cast<const SequenceOfFragments&>(val);
221 return Table == sqf.Table &&
222 SequenceLengthField == sqf.SequenceLengthField &&
223 Fragments == sqf.Fragments;
224 }
225
226 private:
227 BasicOffsetTable Table;
228 VL SequenceLengthField;
230 FragmentVector Fragments;
231 };
232
238 } // end namespace gdcm
239
240 #endif //GDCMSEQUENCEOFFRAGMENTS_H