GDCM 3.0.24
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
30namespace gdcm_ns
31{
32
33struct void_;
34
35// Declaration, also serve as forward declaration
36template<int T> class VRVLSize;
37
38// Implementation when VL is coded on 16 bits:
39template<> class VRVLSize<0> {
40public:
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:
51template<> class VRVLSize<1> {
52public:
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
81template<uint16_t Group, uint16_t Element,
82 long long 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...
86{
87public:
89 enum { VMType = VMToLength<TVM>::Length };
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 guarantee 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 );
191 if( (VR::VRType)VRToEncoding<TVR>::Mode == VR::VRASCII )
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
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( Tag(Group,Element) == de.GetTag() || Group == 0x6000 || Group == 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) {
227 SetFromDataElement( ds.GetDataElement( Tag(Group,Element) ) );
228 }
229 void SetFromDataSet(DataSet const &ds) {
230 if( ds.FindDataElement( Tag(Group,Element) ) &&
231 !ds.GetDataElement( Tag(Group,Element) ).IsEmpty() )
232 {
233 SetFromDataElement( ds.GetDataElement( Tag(Group,Element) ) );
234 }
235 }
236protected:
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 );
283 return EncodingImplementation<VRToEncoding<TVR>::Mode>::Read(Internal,
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);
291 return EncodingImplementation<VRToEncoding<TVR>::Mode>::Write(Internal,
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 );
302 return EncodingImplementation<VRToEncoding<TVR>::Mode>::Read(Internal,
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);
310 return EncodingImplementation<VRToEncoding<TVR>::Mode>::Write(Internal,
311 GetLength(),_os);
312 }
313#endif
314
315};
316
317template<uint16_t Group, uint16_t Element, long long TVR >
318class Attribute<Group,Element,TVR,VM::VM1>
319{
320public:
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 guarantee 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 //}
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( Tag(Group,Element) );
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 );
426 if( (VR::VRType)VRToEncoding<TVR>::Mode == VR::VRASCII )
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
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( Tag(Group,Element) == de.GetTag() || Group == 0x6000 || Group == 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) {
462 SetFromDataElement( ds.GetDataElement( Tag(Group,Element) ) );
463 }
464 void SetFromDataSet(DataSet const &ds) {
465 if( ds.FindDataElement( Tag(Group,Element) ) &&
466 !ds.GetDataElement( Tag(Group,Element) ).IsEmpty() )
467 {
468 SetFromDataElement( ds.GetDataElement( Tag(Group,Element) ) );
469 }
470 }
471protected:
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 );
518 return EncodingImplementation<VRToEncoding<TVR>::Mode>::Read(Internal,
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);
526 return EncodingImplementation<VRToEncoding<TVR>::Mode>::Write(Internal,
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 );
537 return EncodingImplementation<VRToEncoding<TVR>::Mode>::Read(Internal,
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);
545 return EncodingImplementation<VRToEncoding<TVR>::Mode>::Write(Internal,
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
554template<uint16_t Group, uint16_t Element, long long TVR >
555class Attribute<Group,Element,TVR,VM::VM1_n>
556{
557public:
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=nullptr; Length=0; Own = true; }
576 if( Own ) {
577 delete[] Internal;
578 }
579 Internal = nullptr; // paranoid
580 }
581
582 unsigned int GetNumberOfValues() const { return Length; }
583
584 void SetNumberOfValues(unsigned int numel)
585 {
586 SetValues(nullptr, 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 guarantee 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 = nullptr;
628 }
629 Own = own;
630 Length = numel;
631 assert( Internal == nullptr );
632 if( own ) // make a copy:
633 {
634 Internal = new ArrayType[numel];
635 if( array && numel )
636 std::copy(array, array+numel, Internal);
637 }
638 else // pass pointer
639 {
640 Internal = const_cast<ArrayType*>(array);
641 }
642 // postcondition
643 assert( numel == GetNumberOfValues() );
644 }
645
647 DataElement ret( GetTag() );
648 std::ostringstream os;
649 if( Internal )
650 {
652 GetNumberOfValues(),os);
653 if( (VR::VRType)VRToEncoding<TVR>::Mode == VR::VRASCII )
654 {
655 if( GetVR() != VR::UI )
656 {
657 if( os.str().size() % 2 )
658 {
659 os << " ";
660 }
661 }
662 }
663 }
664 ret.SetVR( GetVR() );
665 assert( ret.GetVR() != VR::SQ );
666 VL::Type osStrSize = (VL::Type) os.str().size();
667 ret.SetByteValue( os.str().c_str(), osStrSize);
668 return ret;
669 }
671 // This is kind of hackish but since I do not generate other element than the first one: 0x6000 I should be ok:
672 assert( GetTag() == de.GetTag() || GetTag().GetGroup() == 0x6000
673 || GetTag().GetGroup() == 0x5000 );
674 assert( GetVR().Compatible( de.GetVR() ) ); // In case of VR::INVALID cannot use the & operator
675 assert( !de.IsEmpty() );
676 const ByteValue *bv = de.GetByteValue();
677 SetByteValue(bv);
678 }
679 void Set(DataSet const &ds) {
680 SetFromDataElement( ds.GetDataElement( GetTag() ) );
681 }
682 void SetFromDataSet(DataSet const &ds) {
683 if( ds.FindDataElement( GetTag() ) &&
684 !ds.GetDataElement( GetTag() ).IsEmpty() )
685 {
686 SetFromDataElement( ds.GetDataElement( GetTag() ) );
687 }
688 }
689protected:
690 void SetByteValue(const ByteValue *bv) {
691 assert( bv ); // FIXME
692 std::stringstream ss;
693 std::string s = std::string( bv->GetPointer(), bv->GetLength() );
694 Length = bv->GetLength(); // HACK FIXME
695 ss.str( s );
696 ArrayType *internal;
697 ArrayType buffer[256];
698 if( bv->GetLength() < 256 )
699 {
700 internal = buffer;
701 }
702 else
703 {
704 internal = new ArrayType[(VL::Type)bv->GetLength()]; // over allocation
705 }
706 EncodingImplementation<VRToEncoding<TVR>::Mode>::ReadComputeLength(internal, Length, ss);
707 SetValues( internal, Length, true );
708 if( !(bv->GetLength() < 256) )
709 {
710 delete[] internal;
711 }
712 //EncodingImplementation<VRToEncoding<TVR>::Mode>::Read(Internal,
713 // GetNumberOfValues(),ss);
714 }
715
716private:
717 ArrayType *Internal;
718 unsigned int Length;
719 bool Own : 1;
720};
721
722template<uint16_t Group, uint16_t Element, long long TVR>
723class Attribute<Group,Element,TVR,VM::VM1_3> : public Attribute<Group,Element,TVR,VM::VM1_n>
724{
725public:
726 VM GetVM() const { return VM::VM1_3; }
727};
728
729template<uint16_t Group, uint16_t Element, long long TVR>
730class Attribute<Group,Element,TVR,VM::VM1_8> : public Attribute<Group,Element,TVR,VM::VM1_n>
731{
732public:
733 VM GetVM() const { return VM::VM1_8; }
734};
735
736template<uint16_t Group, uint16_t Element, long long TVR>
737class Attribute<Group,Element,TVR,VM::VM2_n> : public Attribute<Group,Element,TVR,VM::VM1_n>
738{
739public:
740 VM GetVM() const { return VM::VM2_n; }
741};
742
743template<uint16_t Group, uint16_t Element, long long TVR>
744class Attribute<Group,Element,TVR,VM::VM2_2n> : public Attribute<Group,Element,TVR,VM::VM2_n>
745{
746public:
747 static VM GetVM() { return VM::VM2_2n; }
748};
749
750template<uint16_t Group, uint16_t Element, long long TVR>
751class Attribute<Group,Element,TVR,VM::VM3_n> : public Attribute<Group,Element,TVR,VM::VM1_n>
752{
753public:
754 static VM GetVM() { return VM::VM3_n; }
755};
756
757template<uint16_t Group, uint16_t Element, long long TVR>
758class Attribute<Group,Element,TVR,VM::VM3_3n> : public Attribute<Group,Element,TVR,VM::VM3_n>
759{
760public:
761 static VM GetVM() { return VM::VM3_3n; }
762};
763
764
765// For particular case for ASCII string
766// WARNING: This template explicitly instantiates a particular
767// EncodingImplementation THEREFORE it is required to be declared after the
768// EncodingImplementation is needs (doh!)
769#if 0
770template<int TVM>
771class Attribute<TVM>
772{
773public:
774 Attribute(const char array[])
775 {
776 unsigned int i = 0;
777 const char sep = '\\';
778 std::string sarray = array;
779 std::string::size_type pos1 = 0;
780 std::string::size_type pos2 = sarray.find(sep, pos1+1);
781 while(pos2 != std::string::npos)
782 {
783 Internal[i++] = sarray.substr(pos1, pos2-pos1);
784 pos1 = pos2+1;
785 pos2 = sarray.find(sep, pos1+1);
786 }
787 Internal[i] = sarray.substr(pos1, pos2-pos1);
788 // Shouldn't we do the contrary, since we know how many separators
789 // (and default behavior is to discard anything after the VM declared
790 assert( GetLength()-1 == i );
791 }
792
793 unsigned long GetLength() const {
794 return VMToLength<TVM>::Length;
795 }
796 // Implementation of Print is common to all Mode (ASCII/Binary)
797 void Print(std::ostream &_os) const {
798 _os << Internal[0]; // VM is at least guarantee to be one
799 for(int i=1; i<VMToLength<TVM>::Length; ++i)
800 _os << "," << Internal[i];
801 }
802
803 void Read(std::istream &_is) {
804 EncodingImplementation<VR::VRASCII>::Read(Internal, GetLength(),_is);
805 }
806 void Write(std::ostream &_os) const {
807 EncodingImplementation<VR::VRASCII>::Write(Internal, GetLength(),_os);
808 }
809private:
810 typename String Internal[VMToLength<TVM>::Length];
811};
812
813template< int TVM>
814class Attribute<VR::PN, TVM> : public StringAttribute<TVM>
815{
816};
817#endif
818
819#if 0
820
821// Implementation for the undefined length (dynamically allocated array)
822template<int TVR>
823class Attribute<TVR, VM::VM1_n>
824{
825public:
826 // This the way to prevent default initialization
827 explicit Attribute() { Internal=0; Length=0; }
828 ~Attribute() {
829 delete[] Internal;
830 Internal = 0;
831 }
832
833 // Length manipulation
834 // SetLength should really be protected anyway...all operation
835 // should go through SetArray
836 unsigned long GetLength() const { return Length; }
837 typedef typename VRToType<TVR>::Type ArrayType;
838 void SetLength(unsigned long len) {
839 const unsigned int size = sizeof(ArrayType);
840 if( len ) {
841 if( len > Length ) {
842 // perform realloc
843 assert( (len / size) * size == len );
844 ArrayType *internal = new ArrayType[len / size];
845 memcpy(internal, Internal, Length * size);
846 delete[] Internal;
847 Internal = internal;
848 }
849 }
850 Length = len / size;
851 }
852
853 // If save is set to zero user should not delete the pointer
854 //void SetArray(const typename VRToType<TVR>::Type *array, int len, bool save = false)
855 void SetArray(const ArrayType *array, unsigned long len,
856 bool save = false) {
857 if( save ) {
858 SetLength(len); // realloc
859 memcpy(Internal, array, len/*/sizeof(ArrayType)*/);
860 }
861 else {
862 // TODO rewrite this stupid code:
863 Length = len;
864 //Internal = array;
865 assert(0);
866 }
867 }
868 // Implementation of Print is common to all Mode (ASCII/Binary)
869 void Print(std::ostream &_os) const {
870 assert( Length );
871 assert( Internal );
872 _os << Internal[0]; // VM is at least guarantee to be one
873 const unsigned long length = GetLength() < 25 ? GetLength() : 25;
874 for(unsigned long i=1; i<length; ++i)
875 _os << "," << Internal[i];
876 }
877 void Read(std::istream &_is) {
878 EncodingImplementation<VRToEncoding<TVR>::Mode>::Read(Internal,
879 GetLength(),_is);
880 }
881 void Write(std::ostream &_os) const {
882 EncodingImplementation<VRToEncoding<TVR>::Mode>::Write(Internal,
883 GetLength(),_os);
884 }
885
886 Attribute(const Attribute&_val) {
887 if( this != &_val) {
888 *this = _val;
889 }
890 }
891
892 Attribute &operator=(const Attribute &_val) {
893 Length = 0; // SYITF
894 Internal = 0;
895 SetArray(_val.Internal, _val.Length, true);
896 return *this;
897 }
898
899private:
900 typename VRToType<TVR>::Type *Internal;
901 unsigned long Length; // unsigned int ??
902};
903
904//template <int TVM = VM::VM1_n>
905//class Attribute<VR::OB, TVM > : public Attribute<VR::OB, VM::VM1_n> {};
906
907// Partial specialization for derivatives of 1-n : 2-n, 3-n ...
908template<int TVR>
909class Attribute<TVR, VM::VM2_n> : public Attribute<TVR, VM::VM1_n>
910{
911public:
912 typedef Attribute<TVR, VM::VM1_n> Parent;
913 void SetLength(int len) {
914 if( len <= 1 ) return;
915 Parent::SetLength(len);
916 }
917};
918template<int TVR>
919class Attribute<TVR, VM::VM2_2n> : public Attribute<TVR, VM::VM2_n>
920{
921public:
922 typedef Attribute<TVR, VM::VM2_n> Parent;
923 void SetLength(int len) {
924 if( len % 2 ) return;
925 Parent::SetLength(len);
926 }
927};
928template<int TVR>
929class Attribute<TVR, VM::VM3_n> : public Attribute<TVR, VM::VM1_n>
930{
931public:
932 typedef Attribute<TVR, VM::VM1_n> Parent;
933 void SetLength(int len) {
934 if( len <= 2 ) return;
935 Parent::SetLength(len);
936 }
937};
938template<int TVR>
939class Attribute<TVR, VM::VM3_3n> : public Attribute<TVR, VM::VM3_n>
940{
941public:
942 typedef Attribute<TVR, VM::VM3_n> Parent;
943 void SetLength(int len) {
944 if( len % 3 ) return;
945 Parent::SetLength(len);
946 }
947};
948
949
950//template<int T> struct VRToLength;
951//template <> struct VRToLength<VR::AS>
952//{ enum { Length = VM::VM1 }; }
953//template<>
954//class Attribute<VR::AS> : public Attribute<VR::AS, VRToLength<VR::AS>::Length >
955
956// only 0010 1010 AS 1 Patient's Age
957template<>
958class Attribute<VR::AS, VM::VM5>
959{
960public:
961 char Internal[VMToLength<VM::VM5>::Length];
962 void Print(std::ostream &_os) const {
963 _os << Internal;
964 }
965};
966
967template <>
968class Attribute<VR::OB, VM::VM1> : public Attribute<VR::OB, VM::VM1_n> {};
969// Make it impossible to compile any other cases:
970template <int TVM> class Attribute<VR::OB, TVM>;
971
972// Same for OW:
973template <>
974class Attribute<VR::OW, VM::VM1> : public Attribute<VR::OW, VM::VM1_n> {};
975// Make it impossible to compile any other cases:
976template <int TVM> class Attribute<VR::OW, TVM>;
977#endif
978
979#if 0
980template<>
981class Attribute<0x7fe0,0x0010, VR::OW, VM::VM1>
982{
983public:
984 char *Internal;
985 unsigned long Length; // unsigned int ??
986
987 void Print(std::ostream &_os) const {
988 _os << Internal[0];
989 }
990 void SetBytes(char *bytes, unsigned long length) {
991 Internal = bytes;
992 Length = length;
993 }
994 void Read(std::istream &_is) {
995 uint16_t c[2];
996 _is.read((char*)&c, 4);
997 uint32_t l;
998 _is.read((char*)&l, 4);
999 Length = l;
1000 _is.read( Internal, Length );
1001 }
1002 void Write(std::ostream &_os) const {
1003 uint16_t c[] = {0x7fe0, 0x0010};
1004 _os.write((char*)&c, 4);
1005 _os.write((char*)&Length, 4);
1006 _os.write( Internal, Length );
1007 }
1008};
1009#endif
1010
1011/*
1012// Removing Attribute for SQ for now...
1013template<uint16_t Group, uint16_t Element, typename SQA>
1014class Attribute<Group,Element, VR::SQ, VM::VM1, SQA>
1015{
1016public:
1017 SQA sqa;
1018 void Print(std::ostream &_os) const {
1019 _os << Tag(Group,Element);
1020 sqa.Print(_os << std::endl << '\t');
1021 }
1022 void Write(std::ostream &_os) const {
1023 uint16_t c[] = {Group, Element};
1024 _os.write((char*)&c, 4);
1025 uint32_t undef = 0xffffffff;
1026 _os.write((char*)&undef, 4);
1027 uint16_t item_beg[] = {0xfffe,0xe000};
1028 _os.write((char*)&item_beg, 4);
1029 _os.write((char*)&undef, 4);
1030 sqa.Write(_os);
1031 uint16_t item_end[] = {0xfffe,0xe00d};
1032 _os.write((char*)&item_end, 4);
1033 uint32_t zero = 0x0;
1034 _os.write((char*)&zero, 4);
1035 uint16_t seq_end[] = {0xfffe, 0xe0dd};
1036 _os.write((char*)&seq_end, 4);
1037 _os.write((char*)&zero, 4);
1038 }
1039};
1040*/
1041
1047} // namespace gdcm_ns
1048
1049#endif //GDCMATTRIBUTE_H
bool operator!=(const Attribute &att) const
Definition gdcmAttribute.h:375
const ArrayType * GetValues() const
Definition gdcmAttribute.h:413
VRToType< TVR >::Type ArrayType
Definition gdcmAttribute.h:321
static VR GetDictVR()
Definition gdcmAttribute.h:340
void SetValue(ArrayType v)
Definition gdcmAttribute.h:401
DataElement GetAsDataElement() const
Definition gdcmAttribute.h:418
GDCM_STATIC_ASSERT(((((VR::VRType) TVR &VR::VR_VM1) &&((VM::VMType) VM::VM1==VM::VM1))||!((VR::VRType) TVR &VR::VR_VM1)))
void SetFromDataSet(DataSet const &ds)
Definition gdcmAttribute.h:464
void Set(DataSet const &ds)
Definition gdcmAttribute.h:461
void SetFromDataElement(DataElement const &de)
Definition gdcmAttribute.h:441
static VM GetVM()
Definition gdcmAttribute.h:335
void SetByteValue(const ByteValue *bv)
Definition gdcmAttribute.h:489
ArrayType Internal
Definition gdcmAttribute.h:324
bool operator==(const Attribute &att) const
Definition gdcmAttribute.h:370
void SetByteValueNoSwap(const ByteValue *bv)
Definition gdcmAttribute.h:472
static Tag GetTag()
Definition gdcmAttribute.h:333
ArrayType const & GetValue() const
Definition gdcmAttribute.h:394
bool operator<(const Attribute &att) const
Definition gdcmAttribute.h:380
static VM GetDictVM()
Definition gdcmAttribute.h:341
GDCM_STATIC_ASSERT(((VM::VMType) VM::VM1 &(VM::VMType)(TagToType< Group, Element >::VMType)))
static VR GetVR()
Definition gdcmAttribute.h:334
GDCM_STATIC_ASSERT(VMToLength< VM::VM1 >::Length==1)
unsigned int GetNumberOfValues() const
Definition gdcmAttribute.h:346
void Print(std::ostream &os) const
Definition gdcmAttribute.h:352
GDCM_STATIC_ASSERT(((VR::VRType) TVR &(VR::VRType)(TagToType< Group, Element >::VRType)))
ArrayType & GetValue()
Definition gdcmAttribute.h:386
VM GetVM() const
Definition gdcmAttribute.h:726
VM GetVM() const
Definition gdcmAttribute.h:733
void SetValue(ArrayType v)
Definition gdcmAttribute.h:619
void Print(std::ostream &os) const
Definition gdcmAttribute.h:592
ArrayType const & GetValue(unsigned int idx=0) const
Definition gdcmAttribute.h:608
void SetFromDataSet(DataSet const &ds)
Definition gdcmAttribute.h:682
void Set(DataSet const &ds)
Definition gdcmAttribute.h:679
static VR GetVR()
Definition gdcmAttribute.h:567
GDCM_STATIC_ASSERT(((VR::VRType) TVR &(VR::VRType)(TagToType< Group, Element >::VRType)))
~Attribute()
Definition gdcmAttribute.h:575
static Tag GetTag()
Definition gdcmAttribute.h:566
GDCM_STATIC_ASSERT(((((VR::VRType) TVR &VR::VR_VM1) &&((VM::VMType) TagToType< Group, Element >::VMType==VM::VM1))||!((VR::VRType) TVR &VR::VR_VM1)))
unsigned int GetNumberOfValues() const
Definition gdcmAttribute.h:582
void SetNumberOfValues(unsigned int numel)
Definition gdcmAttribute.h:584
static VM GetDictVM()
Definition gdcmAttribute.h:571
DataElement GetAsDataElement() const
Definition gdcmAttribute.h:646
const ArrayType * GetValues() const
Definition gdcmAttribute.h:589
void SetValue(unsigned int idx, ArrayType v)
Definition gdcmAttribute.h:615
Attribute()
Definition gdcmAttribute.h:574
ArrayType & GetValue(unsigned int idx=0)
Definition gdcmAttribute.h:600
VRToType< TVR >::Type ArrayType
Definition gdcmAttribute.h:558
void SetByteValue(const ByteValue *bv)
Definition gdcmAttribute.h:690
GDCM_STATIC_ASSERT((VM::VM1_n &(VM::VMType)(TagToType< Group, Element >::VMType)))
static VR GetDictVR()
Definition gdcmAttribute.h:570
static VM GetVM()
Definition gdcmAttribute.h:568
void SetValues(const ArrayType *array, unsigned int numel, bool own=false)
Definition gdcmAttribute.h:621
void SetFromDataElement(DataElement const &de)
Definition gdcmAttribute.h:670
static VM GetVM()
Definition gdcmAttribute.h:747
VM GetVM() const
Definition gdcmAttribute.h:740
static VM GetVM()
Definition gdcmAttribute.h:761
static VM GetVM()
Definition gdcmAttribute.h:754
Attribute class This class use template metaprograming tricks to let the user know when the template ...
Definition gdcmAttribute.h:86
bool operator==(const Attribute &att) const
Definition gdcmAttribute.h:138
static VR GetVR()
Definition gdcmAttribute.h:99
void SetValue(ArrayType v, unsigned int idx=0)
Definition gdcmAttribute.h:169
const ArrayType * GetValues() const
Definition gdcmAttribute.h:178
void SetByteValue(const ByteValue *bv)
Definition gdcmAttribute.h:254
ArrayType const & GetValue(unsigned int idx=0) const
Definition gdcmAttribute.h:162
ArrayType & GetValue(unsigned int idx=0)
Definition gdcmAttribute.h:154
void SetValues(const ArrayType *array, unsigned int numel=VMType)
Definition gdcmAttribute.h:173
void Set(DataSet const &ds)
Definition gdcmAttribute.h:226
static VM GetVM()
Definition gdcmAttribute.h:100
static Tag GetTag()
Definition gdcmAttribute.h:98
static VR GetDictVR()
Definition gdcmAttribute.h:105
bool operator<(const Attribute &att) const
Definition gdcmAttribute.h:148
VRToType< TVR >::Type ArrayType
Definition gdcmAttribute.h:88
GDCM_STATIC_ASSERT(((VR::VRType) TVR &(VR::VRType)(TagToType< Group, Element >::VRType)))
GDCM_STATIC_ASSERT(((((VR::VRType) TVR &VR::VR_VM1) &&((VM::VMType) TVM==VM::VM1))||!((VR::VRType) TVR &VR::VR_VM1)))
void SetFromDataSet(DataSet const &ds)
Definition gdcmAttribute.h:229
bool operator!=(const Attribute &att) const
Definition gdcmAttribute.h:143
void SetFromDataElement(DataElement const &de)
Definition gdcmAttribute.h:206
DataElement GetAsDataElement() const
Definition gdcmAttribute.h:183
void SetByteValueNoSwap(const ByteValue *bv)
Definition gdcmAttribute.h:237
void Print(std::ostream &os) const
Definition gdcmAttribute.h:117
unsigned int GetNumberOfValues() const
Definition gdcmAttribute.h:111
static VM GetDictVM()
Definition gdcmAttribute.h:106
GDCM_STATIC_ASSERT(((VM::VMType) TVM &(VM::VMType)(TagToType< Group, Element >::VMType)))
Class to represent binary value (array of bytes)
Definition gdcmByteValue.h:35
const char * GetPointer() const
Definition gdcmByteValue.h:110
VL GetLength() const override
Definition gdcmByteValue.h:77
Class to represent a Data Element either Implicit or Explicit.
Definition gdcmDataElement.h:59
const Tag & GetTag() const
Get Tag.
Definition gdcmDataElement.h:67
VR const & GetVR() const
Definition gdcmDataElement.h:84
const ByteValue * GetByteValue() const
Definition gdcmDataElement.h:133
bool IsEmpty() const
Check if Data Element is empty.
Definition gdcmDataElement.h:106
void SetByteValue(const char *array, VL length)
Definition gdcmDataElement.h:126
void SetVR(VR const &vr)
Definition gdcmDataElement.h:88
Class to represent a Data Set (which contains Data Elements)
Definition gdcmDataSet.h:56
const DataElement & GetDataElement(const Tag &t) const
Definition gdcmDataSet.h:188
bool FindDataElement(const PrivateTag &t) const
Look up if private tag 't' is present in the dataset:
Element class.
Definition gdcmElement.h:70
EncodingImplementation.
Definition gdcmElement.h:41
Class to represent a DICOM Data Element (Attribute) Tag (Group, Element).
Definition gdcmTag.h:39
uint32_t Type
Definition gdcmVL.h:32
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:68
VMType
Definition gdcmVM.h:70
static uint16_t Read(std::istream &_is)
Definition gdcmAttribute.h:41
static void Write(std::ostream &os)
Definition gdcmAttribute.h:47
static uint32_t Read(std::istream &_is)
Definition gdcmAttribute.h:53
static void Write(std::ostream &os)
Definition gdcmAttribute.h:62
Definition gdcmAttribute.h:36
VR class.
Definition gdcmVR.h:55
VRType
Definition gdcmVR.h:57
Attribute
Definition gdcmTerminal.h:49
Definition gdcmVM.h:155
Definition gdcmVR.h:242
Definition gdcmVR.h:244