GDCM  2.2.6
gdcmAttribute.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 GDCMATTRIBUTE_H
15 #define GDCMATTRIBUTE_H
16 
17 #include "gdcmTypes.h"
18 #include "gdcmVR.h"
19 #include "gdcmTagToType.h"
20 #include "gdcmVM.h"
21 #include "gdcmElement.h"
22 #include "gdcmDataElement.h"
23 #include "gdcmDataSet.h"
24 #include "gdcmStaticAssert.h"
25 
26 #include <string>
27 #include <vector>
28 #include <sstream>
29 
30 namespace gdcm
31 {
32 
33 struct void_;
34 
35 // Declaration, also serve as forward declaration
36 template<int T> class VRVLSize;
37 
38 // Implementation when VL is coded on 16 bits:
39 template<> class VRVLSize<0> {
40 public:
41  static inline uint16_t Read(std::istream &_is) {
42  uint16_t l;
43  _is.read((char*)&l, 2);
44  return l;
45  }
46 
47  static inline void Write(std::ostream &os) { (void)os;
48  }
49 };
50 // Implementation when VL is coded on 32 bits:
51 template<> class VRVLSize<1> {
52 public:
53  static inline uint32_t Read(std::istream &_is) {
54  char dummy[2];
55  _is.read(dummy, 2);
56 
57  uint32_t l;
58  _is.read((char*)&l, 4);
59  return l;
60  }
61 
62  static inline void Write(std::ostream &os) { (void)os;
63  }
64 };
65 
81 template<uint16_t Group, uint16_t Element,
82  int TVR = TagToType<Group, Element>::VRType, // can the user override this value ?
83  int TVM = TagToType<Group, Element>::VMType // can the user override this value ?
84  /*typename SQAttribute = void_*/ > // if only I had variadic template...
85 class Attribute
86 {
87 public:
88  typedef typename VRToType<TVR>::Type ArrayType;
91 
92  // Make sure that user specified VR/VM are compatible with the public dictionary:
93  GDCM_STATIC_ASSERT( ((VR::VRType)TVR & (VR::VRType)(TagToType<Group, Element>::VRType)) );
94  GDCM_STATIC_ASSERT( ((VM::VMType)TVM & (VM::VMType)(TagToType<Group, Element>::VMType)) );
95  GDCM_STATIC_ASSERT( ((((VR::VRType)TVR & VR::VR_VM1) && ((VM::VMType)TVM == VM::VM1) )
96  || !((VR::VRType)TVR & VR::VR_VM1) ) );
97 
98  static Tag GetTag() { return Tag(Group,Element); }
99  static VR GetVR() { return (VR::VRType)TVR; }
100  static VM GetVM() { return (VM::VMType)TVM; }
101 
102  // The following two methods do make sense only in case of public element,
103  // when the template is intanciated with private element the VR/VM are simply
104  // defaulted to allow everything (see gdcmTagToType.h default template for TagToType)
105  static VR GetDictVR() { return (VR::VRType)(TagToType<Group, Element>::VRType); }
106  static VM GetDictVM() { return (VM::VMType)(TagToType<Group, Element>::VMType); }
107 
108  // Some extra dummy checks:
109  // Data Elements with a VR of SQ, OF, OW, OB or UN shall always have a Value Multiplicity of one.
110 
111  unsigned int GetNumberOfValues() const {
113  }
114  // Implementation of Print is common to all Mode (ASCII/Binary)
115  // TODO: Can we print a \ when in ASCII...well I don't think so
116  // it would mean we used a bad VM then, right ?
117  void Print(std::ostream &os) const {
118  os << GetTag() << " ";
119  os << TagToType<Group,Element>::GetVRString() << " ";
120  os << TagToType<Group,Element>::GetVMString() << " ";
121  os << Internal[0]; // VM is at least garantee to be one
122  for(unsigned int i=1; i<GetNumberOfValues(); ++i)
123  os << "," << Internal[i];
124  }
125 
126  // copy:
127  //ArrayType GetValue(unsigned int idx = 0) {
128  // assert( idx < GetNumberOfValues() );
129  // return Internal[idx];
130  //}
131  //ArrayType operator[] (unsigned int idx) {
132  // return GetValue(idx);
133  //}
134  // FIXME: is this always a good idea ?
135  // I do not think so, I prefer operator
136  //operator ArrayType () const { return Internal[0]; }
137 
138  bool operator==(const Attribute &att) const
139  {
140  return std::equal(Internal, Internal+GetNumberOfValues(),
141  att.GetValues());
142  }
143  bool operator!=(const Attribute &att) const
144  {
145  return !std::equal(Internal, Internal+GetNumberOfValues(),
146  att.GetValues());
147  }
148  bool operator<(const Attribute &att) const
149  {
150  return std::lexicographical_compare(Internal, Internal+GetNumberOfValues(),
151  att.GetValues(), att.GetValues() + att.GetNumberOfValues() );
152  }
153 
154  ArrayType &GetValue(unsigned int idx = 0) {
155  assert( idx < GetNumberOfValues() );
156  return Internal[idx];
157  }
158  ArrayType & operator[] (unsigned int idx) {
159  return GetValue(idx);
160  }
161  // const reference
162  ArrayType const &GetValue(unsigned int idx = 0) const {
163  assert( idx < GetNumberOfValues() );
164  return Internal[idx];
165  }
166  ArrayType const & operator[] (unsigned int idx) const {
167  return GetValue(idx);
168  }
169  void SetValue(ArrayType v, unsigned int idx = 0) {
170  assert( idx < GetNumberOfValues() );
171  Internal[idx] = v;
172  }
173  void SetValues(const ArrayType* array, unsigned int numel = VMType ) {
174  assert( array && numel && numel == GetNumberOfValues() );
175  // std::copy is smarted than a memcpy, and will call memcpy when POD type
176  std::copy(array, array+numel, Internal);
177  }
178  const ArrayType* GetValues() const {
179  return Internal;
180  }
181 
182  // API to talk to the run-time layer: gdcm::DataElement
184  DataElement ret( GetTag() );
185  std::ostringstream os;
186  // os.imbue(std::locale::classic()); // This is not required AFAIK
188  GetNumberOfValues(),os);
189  ret.SetVR( GetVR() );
190  assert( ret.GetVR() != VR::SQ );
192  {
193  if( GetVR() != VR::UI )
194  {
195  if( os.str().size() % 2 )
196  {
197  os << " ";
198  }
199  }
200  }
201  VL::Type osStrSize = (VL::Type)os.str().size();
202  ret.SetByteValue( os.str().c_str(), osStrSize );
203  return ret;
204  }
205 
206  void SetFromDataElement(DataElement const &de) {
207  // This is kind of hackish but since I do not generate other element than the first one: 0x6000 I should be ok:
208  assert( GetTag() == de.GetTag() || GetTag().GetGroup() == 0x6000 || GetTag().GetGroup() == 0x5000 );
209  assert( GetVR() != VR::INVALID );
210  assert( GetVR().Compatible( de.GetVR() ) || de.GetVR() == VR::INVALID ); // In case of VR::INVALID cannot use the & operator
211  if( de.IsEmpty() ) return;
212  const ByteValue *bv = de.GetByteValue();
213 #ifdef GDCM_WORDS_BIGENDIAN
214  if( de.GetVR() == VR::UN /*|| de.GetVR() == VR::INVALID*/ )
215 #else
216  if( de.GetVR() == VR::UN || de.GetVR() == VR::INVALID )
217 #endif
218  {
219  SetByteValue(bv);
220  }
221  else
222  {
223  SetByteValueNoSwap(bv);
224  }
225  }
226  void Set(DataSet const &ds) {
228  }
229  void SetFromDataSet(DataSet const &ds) {
230  if( ds.FindDataElement( GetTag() ) &&
231  !ds.GetDataElement( GetTag() ).IsEmpty() )
232  {
234  }
235  }
236 protected:
237  void SetByteValueNoSwap(const ByteValue *bv) {
238  if( !bv ) return; // That would be bad...
239  assert( bv->GetPointer() && bv->GetLength() ); // [123]C element can be empty
240  //if( VRToEncoding<TVR>::Mode == VR::VRBINARY )
241  // {
242  // // always do a copy !
243  // SetValues(bv->GetPointer(), bv->GetLength());
244  // }
245  //else
246  {
247  std::stringstream ss;
248  std::string s = std::string( bv->GetPointer(), bv->GetLength() );
249  ss.str( s );
251  GetNumberOfValues(),ss);
252  }
253  }
254  void SetByteValue(const ByteValue *bv) {
255  if( !bv ) return; // That would be bad...
256  assert( bv->GetPointer() && bv->GetLength() ); // [123]C element can be empty
257  //if( VRToEncoding<TVR>::Mode == VR::VRBINARY )
258  // {
259  // // always do a copy !
260  // SetValues(bv->GetPointer(), bv->GetLength());
261  // }
262  //else
263  {
264  std::stringstream ss;
265  std::string s = std::string( bv->GetPointer(), bv->GetLength() );
266  ss.str( s );
268  GetNumberOfValues(),ss);
269  }
270  }
271 #if 0 // TODO FIXME the implicit way:
272  // explicit:
273  void Read(std::istream &_is) {
274  const uint16_t cref[] = { Group, Element };
275  uint16_t c[2];
276  _is.read((char*)&c, sizeof(c));
277  assert( c[0] == cref[0] && c[1] == cref[1] );
278  char vr[2];
279  _is.read(vr, 2); // Check consistency ?
280  const uint32_t lref = GetLength() * sizeof( typename VRToType<TVR>::Type );
281  uint32_t l = VRVLSize< (TVR & VR::VL32) >::Read(_is);
282  l /= sizeof( typename VRToType<TVR>::Type );
284  l,_is);
285  }
286  void Write(std::ostream &_os) const {
287  uint16_t c[] = { Group, Element };
288  _os.write((char*)&c, 4);
289  uint32_t l = GetLength() * sizeof( typename VRToType<TVR>::Type );
290  _os.write((char*)&l, 4);
292  GetLength(),_os);
293  }
294  void Read(std::istream &_is) {
295  uint16_t cref[] = { Group, Element };
296  uint16_t c[2];
297  _is.read((char*)&c, 4);
298  const uint32_t lref = GetLength() * sizeof( typename VRToType<TVR>::Type );
299  uint32_t l;
300  _is.read((char*)&l, 4);
301  l /= sizeof( typename VRToType<TVR>::Type );
303  l,_is);
304  }
305  void Write(std::ostream &_os) const {
306  uint16_t c[] = { Group, Element };
307  _os.write((char*)&c, 4);
308  uint32_t l = GetLength() * sizeof( typename VRToType<TVR>::Type );
309  _os.write((char*)&l, 4);
311  GetLength(),_os);
312  }
313 #endif
314 
315 };
316 
317 template<uint16_t Group, uint16_t Element, int TVR >
318 class Attribute<Group,Element,TVR,VM::VM1>
319 {
320 public:
321  typedef typename VRToType<TVR>::Type ArrayType;
323  //ArrayType Internal[VMToLength<TVM>::Length];
326 
327  // Make sure that user specified VR/VM are compatible with the public dictionary:
328  GDCM_STATIC_ASSERT( ((VR::VRType)TVR & (VR::VRType)(TagToType<Group, Element>::VRType)) );
329  GDCM_STATIC_ASSERT( ((VM::VMType)VM::VM1 & (VM::VMType)(TagToType<Group, Element>::VMType)) );
330  GDCM_STATIC_ASSERT( ((((VR::VRType)TVR & VR::VR_VM1) && ((VM::VMType)VM::VM1 == VM::VM1) )
331  || !((VR::VRType)TVR & VR::VR_VM1) ) );
332 
333  static Tag GetTag() { return Tag(Group,Element); }
334  static VR GetVR() { return (VR::VRType)TVR; }
335  static VM GetVM() { return (VM::VMType)VM::VM1; }
336 
337  // The following two methods do make sense only in case of public element,
338  // when the template is intanciated with private element the VR/VM are simply
339  // defaulted to allow everything (see gdcmTagToType.h default template for TagToType)
340  static VR GetDictVR() { return (VR::VRType)(TagToType<Group, Element>::VRType); }
341  static VM GetDictVM() { return (VM::VMType)(TagToType<Group, Element>::VMType); }
342 
343  // Some extra dummy checks:
344  // Data Elements with a VR of SQ, OF, OW, OB or UN shall always have a Value Multiplicity of one.
345 
346  unsigned int GetNumberOfValues() const {
348  }
349  // Implementation of Print is common to all Mode (ASCII/Binary)
350  // TODO: Can we print a \ when in ASCII...well I don't think so
351  // it would mean we used a bad VM then, right ?
352  void Print(std::ostream &os) const {
353  os << GetTag() << " ";
354  os << TagToType<Group,Element>::GetVRString() << " ";
355  os << TagToType<Group,Element>::GetVMString() << " ";
356  os << Internal; // VM is at least garantee to be one
357  }
358  // copy:
359  //ArrayType GetValue(unsigned int idx = 0) {
360  // assert( idx < GetNumberOfValues() );
361  // return Internal[idx];
362  //}
363  //ArrayType operator[] (unsigned int idx) {
364  // return GetValue(idx);
365  //}
366  // FIXME: is this always a good idea ?
367  // I do not think so, I prefer operator
368  //operator ArrayType () const { return Internal[0]; }
369 
370  bool operator==(const Attribute &att) const
371  {
372  return std::equal(&Internal, &Internal+GetNumberOfValues(),
373  att.GetValues());
374  }
375  bool operator!=(const Attribute &att) const
376  {
377  return !std::equal(&Internal, &Internal+GetNumberOfValues(),
378  att.GetValues());
379  }
380  bool operator<(const Attribute &att) const
381  {
382  return std::lexicographical_compare(&Internal, &Internal+GetNumberOfValues(),
383  att.GetValues(), att.GetValues() + att.GetNumberOfValues() );
384  }
385 
387 // assert( idx < GetNumberOfValues() );
388  return Internal;
389  }
390 // ArrayType & operator[] (unsigned int idx) {
391 // return GetValue(idx);
392 // }
393  // const reference
394  ArrayType const &GetValue() const {
395  //assert( idx < GetNumberOfValues() );
396  return Internal;
397  }
398  //ArrayType const & operator[] () const {
399  // return GetValue();
400  //}
401  void SetValue(ArrayType v) {
402 // assert( idx < GetNumberOfValues() );
403  Internal = v;
404  }
405 /* void SetValues(const ArrayType* array, unsigned int numel = VMType ) {
406  assert( array && numel && numel == GetNumberOfValues() );
407  // std::copy is smarted than a memcpy, and will call memcpy when POD type
408  std::copy(array, array+numel, Internal);
409  }
410 */
411 
412  // FIXME Should we remove this function ?
413  const ArrayType* GetValues() const {
414  return &Internal;
415  }
416 
417  // API to talk to the run-time layer: gdcm::DataElement
419  DataElement ret( GetTag() );
420  std::ostringstream os;
421  // os.imbue(std::locale::classic()); // This is not required AFAIK
423  GetNumberOfValues(),os);
424  ret.SetVR( GetVR() );
425  assert( ret.GetVR() != VR::SQ );
427  {
428  if( GetVR() != VR::UI )
429  {
430  if( os.str().size() % 2 )
431  {
432  os << " ";
433  }
434  }
435  }
436  VL::Type osStrSize = (VL::Type)os.str().size();
437  ret.SetByteValue( os.str().c_str(), osStrSize );
438  return ret;
439  }
440 
441  void SetFromDataElement(DataElement const &de) {
442  // This is kind of hackish but since I do not generate other element than the first one: 0x6000 I should be ok:
443  assert( GetTag() == de.GetTag() || GetTag().GetGroup() == 0x6000 || GetTag().GetGroup() == 0x5000 );
444  assert( GetVR() != VR::INVALID );
445  assert( GetVR().Compatible( de.GetVR() ) || de.GetVR() == VR::INVALID ); // In case of VR::INVALID cannot use the & operator
446  if( de.IsEmpty() ) return;
447  const ByteValue *bv = de.GetByteValue();
448 #ifdef GDCM_WORDS_BIGENDIAN
449  if( de.GetVR() == VR::UN /*|| de.GetVR() == VR::INVALID*/ )
450 #else
451  if( de.GetVR() == VR::UN || de.GetVR() == VR::INVALID )
452 #endif
453  {
454  SetByteValue(bv);
455  }
456  else
457  {
458  SetByteValueNoSwap(bv);
459  }
460  }
461  void Set(DataSet const &ds) {
463  }
464  void SetFromDataSet(DataSet const &ds) {
465  if( ds.FindDataElement( GetTag() ) &&
466  !ds.GetDataElement( GetTag() ).IsEmpty() )
467  {
469  }
470  }
471 protected:
472  void SetByteValueNoSwap(const ByteValue *bv) {
473  if( !bv ) return; // That would be bad...
474  assert( bv->GetPointer() && bv->GetLength() ); // [123]C element can be empty
475  //if( VRToEncoding<TVR>::Mode == VR::VRBINARY )
476  // {
477  // // always do a copy !
478  // SetValues(bv->GetPointer(), bv->GetLength());
479  // }
480  //else
481  {
482  std::stringstream ss;
483  std::string s = std::string( bv->GetPointer(), bv->GetLength() );
484  ss.str( s );
486  GetNumberOfValues(),ss);
487  }
488  }
489  void SetByteValue(const ByteValue *bv) {
490  if( !bv ) return; // That would be bad...
491  assert( bv->GetPointer() && bv->GetLength() ); // [123]C element can be empty
492  //if( VRToEncoding<TVR>::Mode == VR::VRBINARY )
493  // {
494  // // always do a copy !
495  // SetValues(bv->GetPointer(), bv->GetLength());
496  // }
497  //else
498  {
499  std::stringstream ss;
500  std::string s = std::string( bv->GetPointer(), bv->GetLength() );
501  ss.str( s );
503  GetNumberOfValues(),ss);
504  }
505  }
506 #if 0 // TODO FIXME the implicit way:
507  // explicit:
508  void Read(std::istream &_is) {
509  const uint16_t cref[] = { Group, Element };
510  uint16_t c[2];
511  _is.read((char*)&c, sizeof(c));
512  assert( c[0] == cref[0] && c[1] == cref[1] );
513  char vr[2];
514  _is.read(vr, 2); // Check consistency ?
515  const uint32_t lref = GetLength() * sizeof( typename VRToType<TVR>::Type );
516  uint32_t l = VRVLSize< (TVR & VR::VL32) >::Read(_is);
517  l /= sizeof( typename VRToType<TVR>::Type );
519  l,_is);
520  }
521  void Write(std::ostream &_os) const {
522  uint16_t c[] = { Group, Element };
523  _os.write((char*)&c, 4);
524  uint32_t l = GetLength() * sizeof( typename VRToType<TVR>::Type );
525  _os.write((char*)&l, 4);
527  GetLength(),_os);
528  }
529  void Read(std::istream &_is) {
530  uint16_t cref[] = { Group, Element };
531  uint16_t c[2];
532  _is.read((char*)&c, 4);
533  const uint32_t lref = GetLength() * sizeof( typename VRToType<TVR>::Type );
534  uint32_t l;
535  _is.read((char*)&l, 4);
536  l /= sizeof( typename VRToType<TVR>::Type );
538  l,_is);
539  }
540  void Write(std::ostream &_os) const {
541  uint16_t c[] = { Group, Element };
542  _os.write((char*)&c, 4);
543  uint32_t l = GetLength() * sizeof( typename VRToType<TVR>::Type );
544  _os.write((char*)&l, 4);
546  GetLength(),_os);
547  }
548 #endif
549 
550 };
551 
552 // No need to repeat default template arg, since primary template
553 // will be used to generate the default arguments
554 template<uint16_t Group, uint16_t Element, int TVR >
555 class Attribute<Group,Element,TVR,VM::VM1_n>
556 {
557 public:
558  typedef typename VRToType<TVR>::Type ArrayType;
559 
560  // Make sure that user specified VR/VM are compatible with the public dictionary:
561  GDCM_STATIC_ASSERT( ((VR::VRType)TVR & (VR::VRType)(TagToType<Group, Element>::VRType)) );
562  GDCM_STATIC_ASSERT( (VM::VM1_n & (VM::VMType)(TagToType<Group, Element>::VMType)) );
563  GDCM_STATIC_ASSERT( ((((VR::VRType)TVR & VR::VR_VM1) && ((VM::VMType)TagToType<Group,Element>::VMType == VM::VM1) )
564  || !((VR::VRType)TVR & VR::VR_VM1) ) );
565 
566  static Tag GetTag() { return Tag(Group,Element); }
567  static VR GetVR() { return (VR::VRType)TVR; }
568  static VM GetVM() { return VM::VM1_n; }
569 
570  static VR GetDictVR() { return (VR::VRType)(TagToType<Group, Element>::VRType); }
571  static VM GetDictVM() { return GetVM(); }
572 
573  // This the way to prevent default initialization
574  explicit Attribute() { Internal=0; Length=0; Own = true; }
576  if( Own ) {
577  delete[] Internal;
578  }
579  Internal = 0; // paranoid
580  }
581 
582  unsigned int GetNumberOfValues() const { return Length; }
583 
584  void SetNumberOfValues(unsigned int numel)
585  {
586  SetValues(NULL, numel, true);
587  }
588 
589  const ArrayType* GetValues() const {
590  return Internal;
591  }
592  void Print(std::ostream &os) const {
593  os << GetTag() << " ";
594  os << GetVR() << " ";
595  os << GetVM() << " ";
596  os << Internal[0]; // VM is at least garantee to be one
597  for(unsigned int i=1; i<GetNumberOfValues(); ++i)
598  os << "," << Internal[i];
599  }
600  ArrayType &GetValue(unsigned int idx = 0) {
601  assert( idx < GetNumberOfValues() );
602  return Internal[idx];
603  }
604  ArrayType &operator[] (unsigned int idx) {
605  return GetValue(idx);
606  }
607  // const reference
608  ArrayType const &GetValue(unsigned int idx = 0) const {
609  assert( idx < GetNumberOfValues() );
610  return Internal[idx];
611  }
612  ArrayType const & operator[] (unsigned int idx) const {
613  return GetValue(idx);
614  }
615  void SetValue(unsigned int idx, ArrayType v) {
616  assert( idx < GetNumberOfValues() );
617  Internal[idx] = v;
618  }
619  void SetValue(ArrayType v) { SetValue(0, v); }
620 
621  void SetValues(const ArrayType *array, unsigned int numel, bool own = false)
622  {
623  if( Internal ) // were we used before ?
624  {
625  // yes !
626  if( Own ) delete[] Internal;
627  Internal = 0;
628  }
629  Own = own;
630  Length = numel;
631  assert( Internal == 0 );
632  if( own ) // make a copy:
633  {
634  assert( /*array &&*/ numel );
635  Internal = new ArrayType[numel];
636  if( array && numel )
637  std::copy(array, array+numel, Internal);
638  }
639  else // pass pointer
640  {
641  Internal = const_cast<ArrayType*>(array);
642  }
643  // postcondition
644  assert( numel == GetNumberOfValues() );
645  }
646 
648  DataElement ret( GetTag() );
649  std::ostringstream os;
650  if( Internal )
651  {
653  GetNumberOfValues(),os);
655  {
656  if( GetVR() != VR::UI )
657  {
658  if( os.str().size() % 2 )
659  {
660  os << " ";
661  }
662  }
663  }
664  }
665  ret.SetVR( GetVR() );
666  assert( ret.GetVR() != VR::SQ );
667  VL::Type osStrSize = (VL::Type) os.str().size();
668  ret.SetByteValue( os.str().c_str(), osStrSize);
669  return ret;
670  }
671  void SetFromDataElement(DataElement const &de) {
672  // This is kind of hackish but since I do not generate other element than the first one: 0x6000 I should be ok:
673  assert( GetTag() == de.GetTag() || GetTag().GetGroup() == 0x6000
674  || GetTag().GetGroup() == 0x5000 );
675  assert( GetVR().Compatible( de.GetVR() ) ); // In case of VR::INVALID cannot use the & operator
676  assert( !de.IsEmpty() );
677  const ByteValue *bv = de.GetByteValue();
678  SetByteValue(bv);
679  }
680  void Set(DataSet const &ds) {
682  }
683  void SetFromDataSet(DataSet const &ds) {
684  if( ds.FindDataElement( GetTag() ) &&
685  !ds.GetDataElement( GetTag() ).IsEmpty() )
686  {
688  }
689  }
690 protected:
691  void SetByteValue(const ByteValue *bv) {
692  assert( bv ); // FIXME
693  std::stringstream ss;
694  std::string s = std::string( bv->GetPointer(), bv->GetLength() );
695  Length = bv->GetLength(); // HACK FIXME
696  ss.str( s );
697  ArrayType *internal;
698  ArrayType buffer[256];
699  if( bv->GetLength() < 256 )
700  {
701  internal = buffer;
702  }
703  else
704  {
705  internal = new ArrayType[(VL::Type)bv->GetLength()]; // over allocation
706  }
707  EncodingImplementation<VRToEncoding<TVR>::Mode>::ReadComputeLength(internal, Length, ss);
708  SetValues( internal, Length, true );
709  if( !(bv->GetLength() < 256) )
710  {
711  delete[] internal;
712  }
713  //EncodingImplementation<VRToEncoding<TVR>::Mode>::Read(Internal,
714  // GetNumberOfValues(),ss);
715  }
716 
717 private:
719  unsigned int Length;
720  bool Own : 1;
721 };
722 
723 template<uint16_t Group, uint16_t Element, int TVR>
724 class Attribute<Group,Element,TVR,VM::VM1_3> : public Attribute<Group,Element,TVR,VM::VM1_n>
725 {
726 public:
727  VM GetVM() const { return VM::VM1_3; }
728 };
729 
730 template<uint16_t Group, uint16_t Element, int TVR>
731 class Attribute<Group,Element,TVR,VM::VM1_8> : public Attribute<Group,Element,TVR,VM::VM1_n>
732 {
733 public:
734  VM GetVM() const { return VM::VM1_8; }
735 };
736 
737 template<uint16_t Group, uint16_t Element, int TVR>
738 class Attribute<Group,Element,TVR,VM::VM2_n> : public Attribute<Group,Element,TVR,VM::VM1_n>
739 {
740 public:
741  VM GetVM() const { return VM::VM2_n; }
742 };
743 
744 template<uint16_t Group, uint16_t Element, int TVR>
745 class Attribute<Group,Element,TVR,VM::VM2_2n> : public Attribute<Group,Element,TVR,VM::VM2_n>
746 {
747 public:
748  static VM GetVM() { return VM::VM2_2n; }
749 };
750 
751 template<uint16_t Group, uint16_t Element, int TVR>
752 class Attribute<Group,Element,TVR,VM::VM3_n> : public Attribute<Group,Element,TVR,VM::VM1_n>
753 {
754 public:
755  static VM GetVM() { return VM::VM3_n; }
756 };
757 
758 template<uint16_t Group, uint16_t Element, int TVR>
759 class Attribute<Group,Element,TVR,VM::VM3_3n> : public Attribute<Group,Element,TVR,VM::VM3_n>
760 {
761 public:
762  static VM GetVM() { return VM::VM3_3n; }
763 };
764 
765 
766 // For particular case for ASCII string
767 // WARNING: This template explicitely instanciates a particular
768 // EncodingImplementation THEREFORE it is required to be declared after the
769 // EncodingImplementation is needs (doh!)
770 #if 0
771 template<int TVM>
772 class Attribute<TVM>
773 {
774 public:
775  Attribute(const char array[])
776  {
777  unsigned int i = 0;
778  const char sep = '\\';
779  std::string sarray = array;
780  std::string::size_type pos1 = 0;
781  std::string::size_type pos2 = sarray.find(sep, pos1+1);
782  while(pos2 != std::string::npos)
783  {
784  Internal[i++] = sarray.substr(pos1, pos2-pos1);
785  pos1 = pos2+1;
786  pos2 = sarray.find(sep, pos1+1);
787  }
788  Internal[i] = sarray.substr(pos1, pos2-pos1);
789  // Shouldn't we do the contrary, since we know how many separators
790  // (and default behavior is to discard anything after the VM declared
791  assert( GetLength()-1 == i );
792  }
793 
794  unsigned long GetLength() const {
795  return VMToLength<TVM>::Length;
796  }
797  // Implementation of Print is common to all Mode (ASCII/Binary)
798  void Print(std::ostream &_os) const {
799  _os << Internal[0]; // VM is at least garantee to be one
800  for(int i=1; i<VMToLength<TVM>::Length; ++i)
801  _os << "," << Internal[i];
802  }
803 
804  void Read(std::istream &_is) {
805  EncodingImplementation<VR::VRASCII>::Read(Internal, GetLength(),_is);
806  }
807  void Write(std::ostream &_os) const {
808  EncodingImplementation<VR::VRASCII>::Write(Internal, GetLength(),_os);
809  }
810 private:
811  typename String Internal[VMToLength<TVM>::Length];
812 };
813 
814 template< int TVM>
815 class Attribute<VR::PN, TVM> : public StringAttribute<TVM>
816 {
817 };
818 #endif
819 
820 #if 0
821 
822 // Implementation for the undefined length (dynamically allocated array)
823 template<int TVR>
824 class Attribute<TVR, VM::VM1_n>
825 {
826 public:
827  // This the way to prevent default initialization
828  explicit Attribute() { Internal=0; Length=0; }
829  ~Attribute() {
830  delete[] Internal;
831  Internal = 0;
832  }
833 
834  // Length manipulation
835  // SetLength should really be protected anyway...all operation
836  // should go through SetArray
837  unsigned long GetLength() const { return Length; }
838  typedef typename VRToType<TVR>::Type ArrayType;
839  void SetLength(unsigned long len) {
840  const unsigned int size = sizeof(ArrayType);
841  if( len ) {
842  if( len > Length ) {
843  // perform realloc
844  assert( (len / size) * size == len );
845  ArrayType *internal = new ArrayType[len / size];
846  memcpy(internal, Internal, Length * size);
847  delete[] Internal;
848  Internal = internal;
849  }
850  }
851  Length = len / size;
852  }
853 
854  // If save is set to zero user should not delete the pointer
855  //void SetArray(const typename VRToType<TVR>::Type *array, int len, bool save = false)
856  void SetArray(const ArrayType *array, unsigned long len,
857  bool save = false) {
858  if( save ) {
859  SetLength(len); // realloc
860  memcpy(Internal, array, len/*/sizeof(ArrayType)*/);
861  }
862  else {
863  // TODO rewrite this stupid code:
864  Length = len;
865  //Internal = array;
866  assert(0);
867  }
868  }
869  // Implementation of Print is common to all Mode (ASCII/Binary)
870  void Print(std::ostream &_os) const {
871  assert( Length );
872  assert( Internal );
873  _os << Internal[0]; // VM is at least garantee to be one
874  const unsigned long length = GetLength() < 25 ? GetLength() : 25;
875  for(unsigned long i=1; i<length; ++i)
876  _os << "," << Internal[i];
877  }
878  void Read(std::istream &_is) {
880  GetLength(),_is);
881  }
882  void Write(std::ostream &_os) const {
884  GetLength(),_os);
885  }
886 
887  Attribute(const Attribute&_val) {
888  if( this != &_val) {
889  *this = _val;
890  }
891  }
892 
893  Attribute &operator=(const Attribute &_val) {
894  Length = 0; // SYITF
895  Internal = 0;
896  SetArray(_val.Internal, _val.Length, true);
897  return *this;
898  }
899 
900 private:
901  typename VRToType<TVR>::Type *Internal;
902  unsigned long Length; // unsigned int ??
903 };
904 
905 //template <int TVM = VM::VM1_n>
906 //class Attribute<VR::OB, TVM > : public Attribute<VR::OB, VM::VM1_n> {};
907 
908 // Partial specialization for derivatives of 1-n : 2-n, 3-n ...
909 template<int TVR>
910 class Attribute<TVR, VM::VM2_n> : public Attribute<TVR, VM::VM1_n>
911 {
912 public:
913  typedef Attribute<TVR, VM::VM1_n> Parent;
914  void SetLength(int len) {
915  if( len <= 1 ) return;
916  Parent::SetLength(len);
917  }
918 };
919 template<int TVR>
920 class Attribute<TVR, VM::VM2_2n> : public Attribute<TVR, VM::VM2_n>
921 {
922 public:
923  typedef Attribute<TVR, VM::VM2_n> Parent;
924  void SetLength(int len) {
925  if( len % 2 ) return;
926  Parent::SetLength(len);
927  }
928 };
929 template<int TVR>
930 class Attribute<TVR, VM::VM3_n> : public Attribute<TVR, VM::VM1_n>
931 {
932 public:
933  typedef Attribute<TVR, VM::VM1_n> Parent;
934  void SetLength(int len) {
935  if( len <= 2 ) return;
936  Parent::SetLength(len);
937  }
938 };
939 template<int TVR>
940 class Attribute<TVR, VM::VM3_3n> : public Attribute<TVR, VM::VM3_n>
941 {
942 public:
943  typedef Attribute<TVR, VM::VM3_n> Parent;
944  void SetLength(int len) {
945  if( len % 3 ) return;
946  Parent::SetLength(len);
947  }
948 };
949 
950 
951 //template<int T> struct VRToLength;
952 //template <> struct VRToLength<VR::AS>
953 //{ enum { Length = VM::VM1 }; }
954 //template<>
955 //class Attribute<VR::AS> : public Attribute<VR::AS, VRToLength<VR::AS>::Length >
956 
957 // only 0010 1010 AS 1 Patient’s Age
958 template<>
959 class Attribute<VR::AS, VM::VM5>
960 {
961 public:
962  char Internal[VMToLength<VM::VM5>::Length];
963  void Print(std::ostream &_os) const {
964  _os << Internal;
965  }
966 };
967 
968 template <>
969 class Attribute<VR::OB, VM::VM1> : public Attribute<VR::OB, VM::VM1_n> {};
970 // Make it impossible to compile any other cases:
971 template <int TVM> class Attribute<VR::OB, TVM>;
972 
973 // Same for OW:
974 template <>
975 class Attribute<VR::OW, VM::VM1> : public Attribute<VR::OW, VM::VM1_n> {};
976 // Make it impossible to compile any other cases:
977 template <int TVM> class Attribute<VR::OW, TVM>;
978 #endif
979 
980 #if 0
981 template<>
982 class Attribute<0x7fe0,0x0010, VR::OW, VM::VM1>
983 {
984 public:
985  char *Internal;
986  unsigned long Length; // unsigned int ??
987 
988  void Print(std::ostream &_os) const {
989  _os << Internal[0];
990  }
991  void SetBytes(char *bytes, unsigned long length) {
992  Internal = bytes;
993  Length = length;
994  }
995  void Read(std::istream &_is) {
996  uint16_t c[2];
997  _is.read((char*)&c, 4);
998  uint32_t l;
999  _is.read((char*)&l, 4);
1000  Length = l;
1001  _is.read( Internal, Length );
1002  }
1003  void Write(std::ostream &_os) const {
1004  uint16_t c[] = {0x7fe0, 0x0010};
1005  _os.write((char*)&c, 4);
1006  _os.write((char*)&Length, 4);
1007  _os.write( Internal, Length );
1008  }
1009 };
1010 #endif
1011 
1012 /*
1013 // Removing Attribute for SQ for now...
1014 template<uint16_t Group, uint16_t Element, typename SQA>
1015 class Attribute<Group,Element, VR::SQ, VM::VM1, SQA>
1016 {
1017 public:
1018  SQA sqa;
1019  void Print(std::ostream &_os) const {
1020  _os << Tag(Group,Element);
1021  sqa.Print(_os << std::endl << '\t');
1022  }
1023  void Write(std::ostream &_os) const {
1024  uint16_t c[] = {Group, Element};
1025  _os.write((char*)&c, 4);
1026  uint32_t undef = 0xffffffff;
1027  _os.write((char*)&undef, 4);
1028  uint16_t item_beg[] = {0xfffe,0xe000};
1029  _os.write((char*)&item_beg, 4);
1030  _os.write((char*)&undef, 4);
1031  sqa.Write(_os);
1032  uint16_t item_end[] = {0xfffe,0xe00d};
1033  _os.write((char*)&item_end, 4);
1034  uint32_t zero = 0x0;
1035  _os.write((char*)&zero, 4);
1036  uint16_t seq_end[] = {0xfffe, 0xe0dd};
1037  _os.write((char*)&seq_end, 4);
1038  _os.write((char*)&zero, 4);
1039  }
1040 };
1041 */
1042 
1048 } // namespace gdcm
1049 
1050 #endif //GDCMATTRIBUTE_H
void Set(DataSet const &ds)
Definition: gdcmAttribute.h:461
void SetVR(VR const &vr)
Definition: gdcmDataElement.h:88
static VR GetDictVR()
Definition: gdcmAttribute.h:105
void SetByteValue(const ByteValue *bv)
Definition: gdcmAttribute.h:489
const ArrayType * GetValues() const
Definition: gdcmAttribute.h:413
static VR GetVR()
Definition: gdcmAttribute.h:99
bool IsEmpty() const
Check if Data Element is empty.
Definition: gdcmDataElement.h:103
Class to represent a Data Set (which contains Data Elements) A Data Set represents an instance of a r...
Definition: gdcmDataSet.h:55
Definition: gdcmVR.h:93
void Set(DataSet const &ds)
Definition: gdcmAttribute.h:680
static Tag GetTag()
Definition: gdcmAttribute.h:566
void Print(std::ostream &os) const
Definition: gdcmAttribute.h:117
static VR GetDictVR()
Definition: gdcmAttribute.h:570
static void Write(std::ostream &os)
Definition: gdcmAttribute.h:62
Definition: gdcmVM.h:103
bool operator==(const Attribute &att) const
Definition: gdcmAttribute.h:370
bool FindDataElement(const PrivateTag &t) const
Look up if private tag &#39;t&#39; is present in the dataset:
static void Read(T *data, unsigned long length, std::istream &_is)
Definition: gdcmElement.h:228
void SetByteValue(const char *array, VL length)
Definition: gdcmDataElement.h:123
VM GetVM() const
Definition: gdcmAttribute.h:734
Definition: gdcmVR.h:59
Definition: gdcmVR.h:223
void SetValue(ArrayType v)
Definition: gdcmAttribute.h:619
bool operator!=(const Attribute &att) const
Definition: gdcmAttribute.h:375
ArrayType Internal[VMToLength< TVM >::Length]
Definition: gdcmAttribute.h:90
VRType
Definition: gdcmVR.h:57
static VM GetDictVM()
Definition: gdcmAttribute.h:341
const DataElement & GetDataElement(const Tag &t) const
Definition: gdcmDataSet.h:178
static VM GetVM()
Definition: gdcmAttribute.h:100
const ArrayType * GetValues() const
Definition: gdcmAttribute.h:589
bool operator<(const Attribute &att) const
Definition: gdcmAttribute.h:148
void SetByteValueNoSwap(const ByteValue *bv)
Definition: gdcmAttribute.h:472
DataElement GetAsDataElement() const
Definition: gdcmAttribute.h:183
void SetValue(ArrayType v, unsigned int idx=0)
Definition: gdcmAttribute.h:169
Definition: gdcmVR.h:98
Definition: gdcmVR.h:225
static Tag GetTag()
Definition: gdcmAttribute.h:333
Definition: gdcmVM.h:102
VRToType< TVR >::Type ArrayType
Definition: gdcmAttribute.h:88
VL GetLength() const
Definition: gdcmByteValue.h:76
VM GetVM() const
Definition: gdcmAttribute.h:741
void SetByteValue(const ByteValue *bv)
Definition: gdcmAttribute.h:254
DataElement GetAsDataElement() const
Definition: gdcmAttribute.h:647
Definition: gdcmVR.h:78
ArrayType const & GetValue() const
Definition: gdcmAttribute.h:394
DataElement GetAsDataElement() const
Definition: gdcmAttribute.h:418
ArrayType Internal
Definition: gdcmAttribute.h:324
Definition: gdcmAttribute.h:89
Element class.
Definition: gdcmElement.h:69
void SetNumberOfValues(unsigned int numel)
Definition: gdcmAttribute.h:584
static VM GetVM()
Definition: gdcmAttribute.h:762
const ByteValue * GetByteValue() const
Definition: gdcmDataElement.h:130
void SetValue(unsigned int idx, ArrayType v)
Definition: gdcmAttribute.h:615
Definition: gdcmVM.h:94
Definition: gdcmVM.h:98
static Tag GetTag()
Definition: gdcmAttribute.h:98
static VM GetVM()
Definition: gdcmAttribute.h:335
GDCM_STATIC_ASSERT(((VR::VRType) TVR &(VR::VRType)(TagToType< Group, Element >::VRType)))
Class to represent a Data Element either Implicit or Explicit.
Definition: gdcmDataElement.h:58
Class to represent binary value (array of bytes)
Definition: gdcmByteValue.h:33
~Attribute()
Definition: gdcmAttribute.h:575
ArrayType const & GetValue(unsigned int idx=0) const
Definition: gdcmAttribute.h:162
void Set(DataSet const &ds)
Definition: gdcmAttribute.h:226
ArrayType & GetValue(unsigned int idx=0)
Definition: gdcmAttribute.h:600
static void Write(const T *data, unsigned long length, std::ostream &_os)
Definition: gdcmElement.h:253
const ArrayType * GetValues() const
Definition: gdcmAttribute.h:178
bool operator!=(const Attribute &att) const
Definition: gdcmAttribute.h:143
Attribute()
Definition: gdcmAttribute.h:574
VR const & GetVR() const
Definition: gdcmDataElement.h:84
Definition: gdcmVM.h:100
void SetValues(const ArrayType *array, unsigned int numel, bool own=false)
Definition: gdcmAttribute.h:621
Value Multiplicity Looking at the DICOMV3 dict only there is very few cases: 1 2 3 4 5 6 8 16 24 1-2 ...
Definition: gdcmVM.h:67
static VM GetVM()
Definition: gdcmAttribute.h:755
void Print(std::ostream &os) const
Definition: gdcmAttribute.h:592
static void Write(std::ostream &os)
Definition: gdcmAttribute.h:47
VRToType< TVR >::Type ArrayType
Definition: gdcmAttribute.h:321
void Print(std::ostream &os) const
Definition: gdcmAttribute.h:352
Attribute class This class use template metaprograming tricks to let the user know when the template ...
Definition: gdcmAttribute.h:85
void SetFromDataElement(DataElement const &de)
Definition: gdcmAttribute.h:441
void SetFromDataSet(DataSet const &ds)
Definition: gdcmAttribute.h:683
static uint32_t Read(std::istream &_is)
Definition: gdcmAttribute.h:53
void SetFromDataElement(DataElement const &de)
Definition: gdcmAttribute.h:671
unsigned int GetNumberOfValues() const
Definition: gdcmAttribute.h:111
void SetByteValueNoSwap(const ByteValue *bv)
Definition: gdcmAttribute.h:237
Definition: gdcmVM.h:154
void SetFromDataSet(DataSet const &ds)
Definition: gdcmAttribute.h:464
Attribute
Definition: gdcmTerminal.h:48
void SetByteValue(const ByteValue *bv)
Definition: gdcmAttribute.h:691
Definition: gdcmVM.h:99
static VM GetDictVM()
Definition: gdcmAttribute.h:106
ArrayType & GetValue()
Definition: gdcmAttribute.h:386
ArrayType & operator[](unsigned int idx)
Definition: gdcmAttribute.h:158
static VR GetVR()
Definition: gdcmAttribute.h:334
const Tag & GetTag() const
Get Tag.
Definition: gdcmDataElement.h:67
unsigned int GetNumberOfValues() const
Definition: gdcmAttribute.h:346
static VM GetVM()
Definition: gdcmAttribute.h:568
static VR GetDictVR()
Definition: gdcmAttribute.h:340
void SetFromDataSet(DataSet const &ds)
Definition: gdcmAttribute.h:229
void SetFromDataElement(DataElement const &de)
Definition: gdcmAttribute.h:206
ArrayType & GetValue(unsigned int idx=0)
Definition: gdcmAttribute.h:154
EncodingImplementation.
Definition: gdcmElement.h:41
void SetValues(const ArrayType *array, unsigned int numel=VMType)
Definition: gdcmAttribute.h:173
const char * GetPointer() const
Definition: gdcmByteValue.h:138
bool operator==(const Attribute &att) const
Definition: gdcmAttribute.h:138
Definition: gdcmVR.h:84
unsigned int GetNumberOfValues() const
Definition: gdcmAttribute.h:582
bool operator<(const Attribute &att) const
Definition: gdcmAttribute.h:380
static uint16_t Read(std::istream &_is)
Definition: gdcmAttribute.h:41
Class to represent a DICOM Data Element (Attribute) Tag (Group, Element). Basically an uint32_t which...
Definition: gdcmTag.h:38
void SetValue(ArrayType v)
Definition: gdcmAttribute.h:401
static VM GetDictVM()
Definition: gdcmAttribute.h:571
uint16_t GetGroup() const
Returns the &#39;Group number&#39; of the given Tag.
Definition: gdcmTag.h:55
VRToType< TVR >::Type ArrayType
Definition: gdcmAttribute.h:558
Definition: gdcmVM.h:76
static VM GetVM()
Definition: gdcmAttribute.h:748
Mode
Definition: gdcmTerminal.h:32
VR class This is adapted from DICOM standard The biggest difference is the INVALID VR and the composi...
Definition: gdcmVR.h:54
VM GetVM() const
Definition: gdcmAttribute.h:727
Definition: gdcmVM.h:91
VMType
Definition: gdcmVM.h:70
Definition: gdcmAttribute.h:36
ArrayType const & GetValue(unsigned int idx=0) const
Definition: gdcmAttribute.h:608
Definition: gdcmVM.h:72
Definition: gdcmVR.h:82
static VR GetVR()
Definition: gdcmAttribute.h:567
uint32_t Type
Definition: gdcmVL.h:32

Generated on Sat Dec 21 2013 05:56:16 for GDCM by doxygen 1.8.5
SourceForge.net Logo