GDCM  2.2.0
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 
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

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