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 GDCMVM_H
15 #define GDCMVM_H
16 
17 #include "gdcmTypes.h"
18 #include <iostream>
19 
20 namespace gdcm
21 {
22 
23 /**
24  * \brief Value Multiplicity
25  * Looking at the DICOMV3 dict only there is very few cases:
26  * 1
27  * 2
28  * 3
29  * 4
30  * 5
31  * 6
32  * 8
33  * 16
34  * 24
35  * 1-2
36  * 1-3
37  * 1-8
38  * 1-32
39  * 1-99
40  * 1-n
41  * 2-2n
42  * 2-n
43  * 3-3n
44  * 3-n
45  *
46  * Some private dict define some more:
47  * 4-4n
48  * 1-4
49  * 1-5
50  * 256
51  * 9
52  * 3-4
53  *
54  * even more:
55  *
56  * 7-7n
57  * 10
58  * 18
59  * 12
60  * 35
61  * 47_47n
62  * 30_30n
63  * 28
64  *
65  * 6-6n
66  */
67 class GDCM_EXPORT VM
68 {
69 public:
70   typedef enum {
71     VM0 = 0, // aka the invalid VM
72     VM1 = 1,
73     VM2 = 2,
74     VM3 = 4,
75     VM4 = 8,
76     VM5 = 16,
77     VM6 = 32,
78     VM8 = 64,
79     VM9 = 128,
80     VM10 = 256,
81     VM12 = 512, //1024,
82     VM16 = 1024, //2048,
83     VM18 = 2048, //4096,
84     VM24 = 4096, //8192,
85     VM28 = 8192, //16384,
86     VM32 = 16384, //32768,
87     VM35 = 32768, //65536,
88     VM99 = 65536, //131072,
89     VM256 = 131072, //262144,
90     VM1_2  = VM1 | VM2,
91     VM1_3  = VM1 | VM2 | VM3,
92     VM1_4  = VM1 | VM2 | VM3 | VM4,
93     VM1_5  = VM1 | VM2 | VM3 | VM4 | VM5,
94     VM1_8  = VM1 | VM2 | VM3 | VM4 | VM5 | VM6 | VM8,
95 // The following need some work:
96     VM1_32 = VM1 | VM2 | VM3 | VM4 | VM5 | VM6 | VM8 | VM9 | VM16 | VM24 | VM32,
97     VM1_99 = VM1 | VM2 | VM3 | VM4 | VM5 | VM6 | VM8 | VM9 | VM16 | VM24 | VM32 | VM99,
98     VM1_n  = VM1 | VM2 | VM3 | VM4 | VM5 | VM6 | VM8 | VM9 | VM16 | VM24 | VM32 | VM99 | VM256,
99     VM2_2n =       VM2       | VM4       | VM6 | VM8       | VM16 | VM24 | VM32        | VM256,
100     VM2_n  =       VM2 | VM3 | VM4 | VM5 | VM6 | VM8 | VM9 | VM16 | VM24 | VM32 | VM99 | VM256,
101     VM3_4  =             VM3 | VM4,
102     VM3_3n =             VM3 |             VM6       | VM9        | VM24        | VM99 | VM256,
103     VM3_n  =             VM3 | VM4 | VM5 | VM6 | VM8 | VM9 | VM16 | VM24 | VM32 | VM99 | VM256,
104     VM4_4n =                   VM4                         | VM16 | VM24 | VM32        | VM256,
105     VM6_6n =                               VM6             | VM12 | VM18 | VM24               ,
106     VM6_n  =                               VM6 | VM8 | VM9 | VM16 | VM24 | VM32 | VM99 | VM256,
107     VM7_7n,
108     VM30_30n,
109     VM47_47n,
110     VM_END = VM1_n + 1  // Custom tag to count number of entry
111   } VMType;
112 
113   /// Return the string as written in the official DICOM dict from
114   /// a custom enum type
115   static const char* GetVMString(VMType vm);
116   static VMType GetVMType(const char *vm);
117 
118   /// Check if vm1 is valid compare to vm2, i.e vm1 is element of vm2
119   /// vm1 is typically deduce from counting in a ValueField
120   static bool IsValid(int vm1, VMType vm2);
121   //bool IsValid() { return VMField != VM0 && VMField < VM_END; }
122 
123   /// WARNING: Implementation deficiency
124   /// The Compatible function is poorly implemented, the reference vm should be coming from
125   /// the dictionary, while the passed in value is the value guess from the file.
126   bool Compatible(VM const &vm) const;
127 
128   ///
129   static VMType GetVMTypeFromLength(size_t length, unsigned int size);
130   static size_t GetNumberOfElementsFromArray(const char *array, size_t length);
131 
VMField(type)132   VM(VMType type = VM0):VMField(type) {}
VMType()133   operator VMType () const { return VMField; }
134   unsigned int GetLength() const;
135 
136   friend std::ostream &operator<<(std::ostream &os, const VM &vm);
137 protected:
138   static unsigned int GetIndex(VMType vm);
139 
140 private:
141   VMType VMField;
142 };
143 //-----------------------------------------------------------------------------
144 inline std::ostream& operator<<(std::ostream& _os, const VM &_val)
145 {
146   assert( VM::GetVMString(_val) );
147   _os << VM::GetVMString(_val);
148   return _os;
149 }
150 
151 //template <int TVM> struct LengthToVM;
152 //template <> struct LengthToVM<1>
153 //{ enum { TVM = VM::VM1 }; };
154 
155 template<int T> struct VMToLength;
156 #define TYPETOLENGTH(type,length) \
157   template<> struct VMToLength<VM::type> \
158   { enum { Length = length }; };
159 // TODO: Could be generated from XML file
160 //TYPETOLENGTH(VM0,1)
161 TYPETOLENGTH(VM1,1)
162 TYPETOLENGTH(VM2,2)
163 TYPETOLENGTH(VM3,3)
164 TYPETOLENGTH(VM4,4)
165 TYPETOLENGTH(VM5,5)
166 TYPETOLENGTH(VM6,6)
167 TYPETOLENGTH(VM8,8)
168 TYPETOLENGTH(VM9,9)
169 TYPETOLENGTH(VM10,10)
170 TYPETOLENGTH(VM12,12)
171 TYPETOLENGTH(VM16,16)
172 TYPETOLENGTH(VM18,18)
173 TYPETOLENGTH(VM24,24)
174 TYPETOLENGTH(VM28,28)
175 TYPETOLENGTH(VM32,32)
176 TYPETOLENGTH(VM35,35)
177 TYPETOLENGTH(VM99,99)
178 TYPETOLENGTH(VM256,256)
179 //TYPETOLENGTH(VM1_2,2)
180 //TYPETOLENGTH(VM1_3,3)
181 //TYPETOLENGTH(VM1_8,8)
182 //TYPETOLENGTH(VM1_32,32)
183 //TYPETOLENGTH(VM1_99,99)
184 //TYPETOLENGTH(VM1_n,
185 //TYPETOLENGTH(VM2_2n,
186 //TYPETOLENGTH(VM2_n,
187 //TYPETOLENGTH(VM3_3n,
188 //TYPETOLENGTH(VM3_n,
189 
190 } // end namespace gdcm
191 
192 #endif //GDCMVM_H
193