GDCM 2.2.1

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

- File List
- File Members

gdcmTag.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 GDCMTAG_H
15 #define GDCMTAG_H
16
17 #include "gdcmTypes.h"
18
19 #include <iostream>
20 #include <iomanip>
21
22 namespace gdcm
23 {
24
38 class GDCM_EXPORT Tag
39 {
40 public:
42 Tag(uint16_t group, uint16_t element) {
43 ElementTag.tags[0] = group; ElementTag.tags[1] = element;
44 }
47 Tag(uint32_t tag = 0) {
48 SetElementTag(tag);
49 }
50
51 friend std::ostream& operator<<(std::ostream &_os, const Tag &_val);
52 friend std::istream& operator>>(std::istream &_is, Tag &_val);
53
55 uint16_t GetGroup() const { return ElementTag.tags[0]; }
57 uint16_t GetElement() const { return ElementTag.tags[1]; }
59 void SetGroup(uint16_t group) { ElementTag.tags[0] = group; }
61 void SetElement(uint16_t element) { ElementTag.tags[1] = element; }
63 void SetElementTag(uint16_t group, uint16_t element) {
64 ElementTag.tags[0] = group; ElementTag.tags[1] = element;
65 }
66
68 uint32_t GetElementTag() const {
69 #ifndef GDCM_WORDS_BIGENDIAN
70 return (ElementTag.tag<<16) | (ElementTag.tag>>16);
71 #else
72 return ElementTag.tag;
73 #endif
74 }
75
77 void SetElementTag(uint32_t tag) {
78 #ifndef GDCM_WORDS_BIGENDIAN
79 tag = ( (tag<<16) | (tag>>16) );
80 #endif
81 ElementTag.tag = tag;
82 }
83
85 const uint16_t &operator[](const unsigned int &_id) const
86 {
87 assert(_id<2);
88 return ElementTag.tags[_id];
89 }
91 uint16_t &operator[](const unsigned int &_id)
92 {
93 assert(_id<2);
94 return ElementTag.tags[_id];
95 }
96
97 Tag &operator=(const Tag &_val)
98 {
99 ElementTag.tag = _val.ElementTag.tag;
100 return *this;
101 }
102
103 bool operator==(const Tag &_val) const
104 {
105 return ElementTag.tag == _val.ElementTag.tag;
106 }
107 bool operator!=(const Tag &_val) const
108 {
109 return ElementTag.tag != _val.ElementTag.tag;
110 }
111
114 // FIXME FIXME FIXME TODO
115 // the following is pretty dumb. Since we have control over who is group
116 // and who is element, we should reverse them in little endian and big endian case
117 // since what we really want is fast comparison and not garantee that group is in #0
118 // ...
119 bool operator<(const Tag &_val) const
120 {
121 #ifndef GDCM_WORDS_BIGENDIAN
122 if( ElementTag.tags[0] < _val.ElementTag.tags[0] )
123 return true;
124 if( ElementTag.tags[0] == _val.ElementTag.tags[0]
125 && ElementTag.tags[1] < _val.ElementTag.tags[1] )
126 return true;
127 return false;
128 #else
129 // Plain comparison is enough!
130 return ( ElementTag.tag < _val.ElementTag.tag );
131 #endif
132 }
133 bool operator<=(const Tag &t2) const
134 {
135 const Tag &t1 = *this;
136 return t1 == t2 || t1 < t2;
137 }
138
139 Tag(const Tag &_val)
140 {
141 ElementTag.tag = _val.ElementTag.tag;
142 }
144 uint32_t GetLength() const { return 4; }
145
150 bool IsPublic() const { return !(ElementTag.tags[0] % 2); }
151
155 bool IsPrivate() const { return !IsPublic(); }
156
157 //-----------------------------------------------------------------------------
159 template <typename TSwap>
160 std::istream &Read(std::istream &is)
161 {
162 if( is.read(ElementTag.bytes, 4) )
163 TSwap::SwapArray(ElementTag.tags, 2);
164 return is;
165 }
166
168 template <typename TSwap>
169 const std::ostream &Write(std::ostream &os) const
170 {
171 uint16_t copy[2];
172 copy[0]= ElementTag.tags[0];
173 copy[1]= ElementTag.tags[1];
174 TSwap::SwapArray(copy, 2);
175 return os.write((char*)(&copy), 4);
176 }
177
179 Tag GetPrivateCreator() const
180 {
181 // See PS 3.5 - 7.8.1 PRIVATE DATA ELEMENT TAGS
182 // eg: 0x0123,0x1425 -> 0x0123,0x0014
183 assert( IsPrivate() && !IsPrivateCreator() );
184 Tag r = *this;
185 r.SetElement( (uint16_t)(GetElement() >> 8) );
186 return r;
187 }
189 void SetPrivateCreator(Tag const &t)
190 {
191 // See PS 3.5 - 7.8.1 PRIVATE DATA ELEMENT TAGS
192 // eg: 0x0123,0x0045 -> 0x0123,0x4567
193 assert( t.IsPrivate() /*&& t.IsPrivateCreator()*/ );
194 uint16_t element = (uint16_t)(t.GetElement() << 8);
195 uint16_t base = (uint16_t)(GetElement() << 8);
196 SetElement( (uint16_t)((base >> 8) + element) );
197 }
198
201 bool IsPrivateCreator() const
202 {
203 return IsPrivate() && (GetElement() <= 0xFF && GetElement() >= 0x10);
204 }
205
207 bool IsIllegal() const
208 {
209 // DICOM reserved those groups:
210 return GetGroup() == 0x0001 || GetGroup() == 0x0003 || GetGroup() == 0x0005 || GetGroup() == 0x0007
211 // This is a very special case, in private group, one cannot use element [0x01,0x09] ...
212 // || (IsPrivate() && !IsPrivateCreator() && !IsGroupLength());
213 || (IsPrivate() && GetElement() > 0x0 && GetElement() < 0x10 );
214 }
215
217 bool IsGroupLength() const
218 {
219 return GetElement() == 0x0;
220 }
221
223 bool IsGroupXX(const Tag &t) const
224 {
225 if( t.GetElement() == GetElement() )
226 {
227 if( t.IsPrivate() ) return false;
228 uint16_t group = (uint16_t)((GetGroup() >> 8 ) << 8);
229 return group == t.GetGroup();
230 }
231 return false;
232 }
233
239 bool ReadFromCommaSeparatedString(const char *str);
240
243 bool ReadFromPipeSeparatedString(const char *str);
244
247 std::string PrintAsPipeSeparatedString() const;
248
249 private:
250 union { uint32_t tag; uint16_t tags[2]; char bytes[4]; } ElementTag;
251 };
252 //-----------------------------------------------------------------------------
253 inline std::istream& operator>>(std::istream &_is, Tag &_val)
254 {
255 char c;
256 _is >> c;
257 uint16_t a, b;
258 _is >> std::hex >> a;
259 //_is >> std::hex >> _val[0];
260 //_is >> std::hex >> _val.ElementTag.tags[0];
261 _is >> c;
262 //_is >> _val[1];
263 //_is >> std::hex >> _val.ElementTag.tags[1];
264 _is >> std::hex >> b;
265 _is >> c;
266 _val.SetGroup( a );
267 _val.SetElement( b );
268 return _is;
269 }
270
271 inline std::ostream& operator<<(std::ostream &_os, const Tag &_val)
272 {
273 _os.setf( std::ios::right);
274 _os << std::hex << '(' << std::setw( 4 ) << std::setfill( '0' )
275 << _val[0] << ',' << std::setw( 4 ) << std::setfill( '0' )
276 << _val[1] << ')' << std::setfill( ' ' ) << std::dec;
277 return _os;
278 }
279
280 } // end namespace gdcm
281
282 #endif //GDCMTAG_H