GDCM 2.2.1

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

- File List
- File Members

gdcmFragment.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 GDCMFRAGMENT_H
15 #define GDCMFRAGMENT_H
16
17 #include "gdcmDataElement.h"
18 #include "gdcmByteValue.h"
19 #include "gdcmSmartPointer.h"
20 #include "gdcmParseException.h"
21
22 namespace gdcm
23 {
24
25 // Implementation detail:
26 // I think Fragment should be a protected sublclass of DataElement:
27 // looking somewhat like this:
28 /*
29 class GDCM_EXPORT Fragment : protected DataElement
30 {
31 public:
32 using DataElement::GetTag;
33 using DataElement::GetVL;
34 using DataElement::SetByteValue;
35 using DataElement::GetByteValue;
36 using DataElement::GetValue;
37 */
38 // Instead I am only hiding the SetTag member...
39
43 class GDCM_EXPORT Fragment : public DataElement
44 {
45 //protected:
46 // void SetTag(const Tag &t);
47 public:
48 Fragment() : DataElement(Tag(0xfffe, 0xe000), 0) {}
49 friend std::ostream &operator<<(std::ostream &os, const Fragment &val);
50
51 VL GetLength() const {
52 assert( !ValueLengthField.IsUndefined() );
53 assert( !ValueField || ValueField->GetLength() == ValueLengthField );
54 return TagField.GetLength() + ValueLengthField.GetLength()
55 + ValueLengthField;
56 }
57
58 template <typename TSwap>
59 std::istream &Read(std::istream &is)
60 {
61 ReadPreValue<TSwap>(is);
62 return ReadValue<TSwap>(is);
63 }
64
65 template <typename TSwap>
66 std::istream &ReadPreValue(std::istream &is)
67 {
68 const Tag itemStart(0xfffe, 0xe000);
69 const Tag seqDelItem(0xfffe,0xe0dd);
70
71 TagField.Read<TSwap>(is);
72 if( !is )
73 {
74 // BogusItemStartItemEnd.dcm
75 throw Exception( "Problem" );
76 return is;
77 }
78 if( !ValueLengthField.Read<TSwap>(is) )
79 {
80 // GENESIS_SIGNA-JPEG-CorruptFrag.dcm
81 // JPEG fragment is declared to have 61902, but infact really is only 61901
82 // so we end up reading 0xddff,0x00e0, and VL = 0x0 (1 byte)
83 throw Exception( "Problem" );
84 return is;
85 }
86 #ifdef GDCM_SUPPORT_BROKEN_IMPLEMENTATION
87 if( TagField != itemStart && TagField != seqDelItem )
88 {
89 throw Exception( "Problem" );
90 }
91 #endif
92 return is;
93 }
94
95 template <typename TSwap>
96 std::istream &ReadValue(std::istream &is)
97 {
98 // Superclass
99 const Tag itemStart(0xfffe, 0xe000);
100 const Tag seqDelItem(0xfffe,0xe0dd);
101 // Self
102 SmartPointer<ByteValue> bv = new ByteValue;
103 bv->SetLength(ValueLengthField);
104 if( !bv->Read<TSwap>(is) )
105 {
106 // Fragment is incomplete, but is a itemStart, let's try to push it anyway...
107 gdcmWarningMacro( "Fragment could not be read" );
108 //bv->SetLength(is.gcount());
109 ValueField = bv;
110 ParseException pe;
111 pe.SetLastElement( *this );
112 throw pe;
113 return is;
114 }
115 ValueField = bv;
116 return is;
117 }
118
119
120 template <typename TSwap>
121 std::ostream &Write(std::ostream &os) const {
122 const Tag itemStart(0xfffe, 0xe000);
123 const Tag seqDelItem(0xfffe,0xe0dd);
124 if( !TagField.Write<TSwap>(os) )
125 {
126 assert(0 && "Should not happen");
127 return os;
128 }
129 assert( TagField == itemStart
130 || TagField == seqDelItem );
131 const ByteValue *bv = GetByteValue();
132 // VL
133 // The following piece of code is hard to read in order to support such broken file as:
134 // CompressedLossy.dcm
135 if( IsEmpty() )
136 {
137 //assert( bv );
138 VL zero = 0;
139 if( !zero.Write<TSwap>(os) )
140 {
141 assert(0 && "Should not happen");
142 return os;
143 }
144 }
145 else
146 {
147 assert( ValueLengthField );
148 if( !ValueLengthField.Write<TSwap>(os) )
149 {
150 assert(0 && "Should not happen");
151 return os;
152 }
153 }
154 // Value
155 if( ValueLengthField && bv )
156 {
157 // Self
158 assert( bv );
159 assert( bv->GetLength() == ValueLengthField );
160 if( !bv->Write<TSwap>(os) )
161 {
162 assert(0 && "Should not happen");
163 return os;
164 }
165 }
166 return os;
167 }
168 };
169 //-----------------------------------------------------------------------------
170 inline std::ostream &operator<<(std::ostream &os, const Fragment &val)
171 {
172 os << "Tag: " << val.TagField;
173 os << "\tVL: " << val.ValueLengthField;
174 if( val.ValueField )
175 {
176 os << "\t" << *(val.ValueField);
177 }
178
179 return os;
180 }
181
182 } // end namespace gdcm
183
184 #endif //GDCMFRAGMENT_H