GDCM 2.2.1

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

- File List
- File Members

gdcmVR.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 GDCMVR_H
15 #define GDCMVR_H
16
17 #include "gdcmTag.h"
18 #include "gdcmTrace.h"
19 #include "gdcmString.h"
20
21 #include <iostream>
22 #include <fstream>
23 #include <assert.h>
24
25 //these defines are here to ensure compilation on sunos gcc
26 #if defined (CS)
27 # undef CS
28 #endif
29 #if defined (DS)
30 # undef DS
31 #endif
32 #if defined (SS)
33 # undef SS
34 #endif
35
36
37 namespace gdcm
38 {
39
54 class GDCM_EXPORT VR
55 {
56 public:
57 typedef enum {
58 // Warning: Do not write if ( vr & VR::INVALID ) but if ( vr == VR::INVALID )
59 INVALID = 0, // For Item/(Seq) Item Delimitation Item
60 AE = 1,
61 AS = 2,
62 AT = 4,
63 CS = 8,
64 DA = 16,
65 DS = 32,
66 DT = 64,
67 FD = 128,
68 FL = 256,
69 IS = 512,
70 LO = 1024,
71 LT = 2048,
72 OB = 4096,
73 OF = 8192,
74 OW = 16384,
75 PN = 32768,
76 SH = 65536,
77 SL = 131072,
78 SQ = 262144,
79 SS = 524288,
80 ST = 1048576,
81 TM = 2097152,
82 UI = 4194304,
83 UL = 8388608,
84 UN = 16777216,
85 US = 33554432,
86 UT = 67108864,
87 OB_OW = OB | OW,
88 US_SS = US | SS,
89 US_SS_OW = US | SS | OW,
90 // The following do not have a VRString equivalent (ie cannot be found in PS 3.6)
91 VL16 = AE | AS | AT | CS | DA | DS | DT | FD | FL | IS | LO | LT | PN | SH | SL | SS | ST | TM | UI | UL | US, // if( VR & VL16 ) => VR has its VL coded over 16bits
92 VL32 = OB | OW | OF | SQ | UN | UT, // if( VR & VL32 ) => VR has its VL coded over 32bits
93 VRASCII = AE | AS | CS | DA | DS | DT | IS | LO | LT | PN | SH | ST | TM | UI | UT,
94 VRBINARY = AT | FL | FD | OB | OF | OW | SL | SQ | SS | UL | UN | US, // FIXME: UN ?
95 // PS 3.5:
96 // Data Elements with a VR of SQ, OF, OW, OB or UN shall always have a Value Multiplicity of one.
97 // GDCM is adding a couple more: AS, LT, ST, UT
98 VR_VM1 = AS | LT | ST | UT | SQ | OF | OW | OB | UN, // All those VR have a VM1
99 VRALL = VRASCII | VRBINARY,
100 VR_END = UT+1 // Invalid VR, need to be max(VRType)+1
101 } VRType;
102
103 static const char *GetVRString(VRType vr);
104
105 // This function will only look at the very first two chars nothing else
106 static VRType GetVRTypeFromFile(const char *vr);
107
108 // You need to make sure end of string is \0
109 static VRType GetVRType(const char *vr);
110 static const char *GetVRStringFromFile(VRType vr);
111
112 static bool IsValid(const char *vr);
113 // Check if vr1 is valid against vr2,
114 // Typically vr1 is read from the file and vr2 is taken from the dict
115 static bool IsValid(const char *vr1, VRType vr2);
116 //static bool IsValid(const VRType &vr1, const VRType &vr2);
117 // Find out if the string read is byte swapped
118 static bool IsSwap(const char *vr);
119
120 // Size read on disk
121 // FIXME: int ?
122 int GetLength() const {
123 return VR::GetLength(VRField);
124 }
125 unsigned int GetSizeof() const;
126 static uint32_t GetLength(VRType vr) {
127 //if( vr == VR::INVALID ) return 4;
128 if( vr & VL32 )
129 {
130 return 4;
131 }
132 else
133 return 2;
134 }
135
136 // Some use of template metaprograming with ugly macro
137 static bool IsBinary(VRType vr);
138 static bool IsASCII(VRType vr);
139 // TODO: REMOVE ME
140 static bool CanDisplay(VRType vr);
141 // TODO: REMOVE ME
142 static bool IsBinary2(VRType vr);
143 // TODO: REMOVE ME
144 static bool IsASCII2(VRType vr);
145
146 VR(VRType vr = INVALID):VRField(vr) { }
147 //VR(VR const &vr):VRField(vr.VRField) { }
148 std::istream &Read(std::istream &is)
149 {
150 char vr[2];
151 is.read(vr, 2);
152 VRField = GetVRTypeFromFile(vr);
153 assert( VRField != VR::VR_END );
154 //assert( VRField != VR::INVALID );
155 if( VRField == VR::INVALID ) throw Exception( "INVALID VR" );
156 if( VRField & VL32 )
157 {
158 #if 0
159 // For some reason this seems slower on my linux box...
160 is.seekg(2, std::ios::cur );
161 #else
162 char dum[2];
163 is.read(dum, 2);
164 if( !(dum[0] == 0 && dum[1] == 0 ))
165 {
166 // JDDICOM_Sample4.dcm
167 gdcmDebugMacro( "32bits VR contains non zero bytes. Skipped" );
168 }
169 #endif
170 }
171 return is;
172 }
173
174 const std::ostream &Write(std::ostream &os) const
175 {
176 VRType vrfield = VRField;
177 gdcmAssertAlwaysMacro( !IsDual() );
178 if( vrfield == VR::INVALID )
179 {
180 //vrfield = VR::UN;
181 }
182 const char *vr = GetVRString(vrfield);
183 //assert( strlen( vr ) == 2 );
184 assert( vr[0] && vr[1] && vr[2] == 0 );
185 os.write(vr, 2);
186 // See PS 3.5, Data Element Structure With Explicit VR
187 if( vrfield & VL32 )
188 {
189 const char dum[2] = {0, 0};
190 os.write(dum,2);
191 }
192 return os;
193 }
194 friend std::ostream &operator<<(std::ostream &os, const VR &vr);
195
196 operator VRType () const { return VRField; }
197
198 unsigned int GetSize() const;
199
200 bool Compatible(VR const &vr) const;
201
202 bool IsVRFile() const;
203
204 bool IsDual() const;
205
206 private:
207 // Internal function that map a VRType to an index in the VRStrings table
208 static int GetIndex(VRType vr);
209 VRType VRField;
210 };
211 //-----------------------------------------------------------------------------
212 inline std::ostream &operator<<(std::ostream &_os, const VR &val)
213 {
214 //_os << VR::GetVRStringFromFile(val.VRField);
215 _os << VR::GetVRString(val.VRField);
216 return _os;
217 }
218
219 // Apparently SWIG is not happy with something, somewhere below...
220 #ifndef SWIG
221
222 // Tells whether VR Type is ASCII or Binary
223 template<int T> struct VRToEncoding;
224 // Convert from VR Type to real underlying type
225 template<int T> struct VRToType;
226 #define TYPETOENCODING(type,rep, rtype) \
227 template<> struct VRToEncoding<VR::type> \
228 { enum { Mode = VR::rep }; }; \
229 template<> struct VRToType<VR::type> \
230 { typedef rtype Type; };
231
232
233 // Do not use me
234 struct UI { char Internal[64+1];
235 friend std::ostream& operator<<(std::ostream &_os, const UI &_val);
236 };
237 inline std::ostream& operator<<(std::ostream &_os, const UI &_val)
238 {
239 _os << _val.Internal;
240 return _os;
241 }
242
243 typedef String<'\\',16> AEComp;
244 typedef String<'\\',64> ASComp;
245 typedef String<'\\',16> CSComp;
246 typedef String<'\\',64> DAComp;
247 typedef String<'\\',64> DTComp;
248 typedef String<'\\',64> LOComp;
249 typedef String<'\\',64> LTComp;
250 typedef String<'\\',64> PNComp;
251 typedef String<'\\',64> SHComp;
252 typedef String<'\\',64> STComp;
253 typedef String<'\\',16> TMComp;
254 typedef String<'\\',64,0> UIComp;
255 typedef String<'\\',64> UTComp;
256
257
258 // TODO: Could be generated from XML file
259 TYPETOENCODING(AE,VRASCII ,AEComp)
260 TYPETOENCODING(AS,VRASCII ,ASComp)
261 TYPETOENCODING(AT,VRBINARY,Tag)
262 TYPETOENCODING(CS,VRASCII ,CSComp)
263 TYPETOENCODING(DA,VRASCII ,DAComp)
264 TYPETOENCODING(DS,VRASCII ,double)
265 TYPETOENCODING(DT,VRASCII ,DTComp)
266 TYPETOENCODING(FL,VRBINARY,float)
267 TYPETOENCODING(FD,VRBINARY,double)
268 TYPETOENCODING(IS,VRASCII ,int32_t)
269 TYPETOENCODING(LO,VRASCII ,LOComp)
270 TYPETOENCODING(LT,VRASCII ,LTComp)
271 TYPETOENCODING(OB,VRBINARY,uint8_t)
272 TYPETOENCODING(OF,VRBINARY,float)
273 TYPETOENCODING(OW,VRBINARY,uint16_t)
274 TYPETOENCODING(PN,VRASCII ,PNComp)
275 TYPETOENCODING(SH,VRASCII ,SHComp)
276 TYPETOENCODING(SL,VRBINARY,int32_t)
277 TYPETOENCODING(SQ,VRBINARY,unsigned char) // FIXME
278 TYPETOENCODING(SS,VRBINARY,int16_t)
279 TYPETOENCODING(ST,VRASCII ,STComp)
280 TYPETOENCODING(TM,VRASCII ,TMComp)
281 TYPETOENCODING(UI,VRASCII ,UIComp)
282 TYPETOENCODING(UL,VRBINARY,uint32_t)
283 TYPETOENCODING(UN,VRBINARY,uint8_t) // FIXME ?
284 TYPETOENCODING(US,VRBINARY,uint16_t)
285 TYPETOENCODING(UT,VRASCII ,UTComp)
286
287 #define VRTypeTemplateCase(type) \
288 case VR::type: \
289 return sizeof ( VRToType<VR::type>::Type );
290
291 inline unsigned int VR::GetSize() const
292 {
293 switch(VRField)
294 {
295 VRTypeTemplateCase(AE)
296 VRTypeTemplateCase(AS)
297 VRTypeTemplateCase(AT)
298 VRTypeTemplateCase(CS)
299 VRTypeTemplateCase(DA)
300 VRTypeTemplateCase(DS)
301 VRTypeTemplateCase(DT)
302 VRTypeTemplateCase(FL)
303 VRTypeTemplateCase(FD)
304 VRTypeTemplateCase(IS)
305 VRTypeTemplateCase(LO)
306 VRTypeTemplateCase(LT)
307 VRTypeTemplateCase(OB)
308 VRTypeTemplateCase(OF)
309 VRTypeTemplateCase(OW)
310 VRTypeTemplateCase(PN)
311 VRTypeTemplateCase(SH)
312 VRTypeTemplateCase(SL)
313 VRTypeTemplateCase(SQ)
314 VRTypeTemplateCase(SS)
315 VRTypeTemplateCase(ST)
316 VRTypeTemplateCase(TM)
317 VRTypeTemplateCase(UI)
318 VRTypeTemplateCase(UL)
319 VRTypeTemplateCase(UN)
320 VRTypeTemplateCase(US)
321 VRTypeTemplateCase(UT)
322 case VR::US_SS:
323 return 2;
324 default:
325 assert( 0 && "should not" );
326 }
327 return 0;
328 }
329 #endif // SWIG
330
331
332 } // end namespace gdcm
333
334 #endif //GDCMVR_H