/src/dcmtk/dcmdata/libsrc/dcvr.cc
Line | Count | Source |
1 | | /* |
2 | | * |
3 | | * Copyright (C) 1994-2024, OFFIS e.V. |
4 | | * All rights reserved. See COPYRIGHT file for details. |
5 | | * |
6 | | * This software and supporting documentation were developed by |
7 | | * |
8 | | * OFFIS e.V. |
9 | | * R&D Division Health |
10 | | * Escherweg 2 |
11 | | * D-26121 Oldenburg, Germany |
12 | | * |
13 | | * |
14 | | * Module: dcmdata |
15 | | * |
16 | | * Author: Gerd Ehlers, Andreas Barth, Andrew Hewett |
17 | | * |
18 | | * Purpose: class DcmVR: Value Representation |
19 | | * |
20 | | * |
21 | | */ |
22 | | |
23 | | |
24 | | #include "dcmtk/config/osconfig.h" /* make sure OS specific configuration is included first */ |
25 | | #include "dcmtk/dcmdata/dcvr.h" |
26 | | #include "dcmtk/dcmdata/dctypes.h" |
27 | | #include <cstring> |
28 | | |
29 | | /* |
30 | | ** global flags |
31 | | */ |
32 | | OFGlobal<OFBool> dcmEnableUnknownVRGeneration(OFTrue); |
33 | | OFGlobal<OFBool> dcmEnableUnlimitedTextVRGeneration(OFTrue); |
34 | | OFGlobal<OFBool> dcmEnableOtherFloatVRGeneration(OFTrue); |
35 | | OFGlobal<OFBool> dcmEnableOtherDoubleVRGeneration(OFTrue); |
36 | | OFGlobal<OFBool> dcmEnableOtherLongVRGeneration(OFTrue); |
37 | | OFGlobal<OFBool> dcmEnableUniversalResourceIdentifierOrLocatorVRGeneration(OFTrue); |
38 | | OFGlobal<OFBool> dcmEnableUnlimitedCharactersVRGeneration(OFTrue); |
39 | | OFGlobal<OFBool> dcmEnableOther64bitVeryLongVRGeneration(OFTrue); |
40 | | OFGlobal<OFBool> dcmEnableSigned64bitVeryLongVRGeneration(OFTrue); |
41 | | OFGlobal<OFBool> dcmEnableUnsigned64bitVeryLongVRGeneration(OFTrue); |
42 | | OFGlobal<OFBool> dcmEnableUnknownVRConversion(OFFalse); |
43 | | |
44 | | /* |
45 | | ** global functions |
46 | | */ |
47 | | void dcmEnableGenerationOfNewVRs() |
48 | 0 | { |
49 | 0 | dcmEnableUnknownVRGeneration.set(OFTrue); |
50 | 0 | dcmEnableUnlimitedTextVRGeneration.set(OFTrue); |
51 | 0 | dcmEnableOtherFloatVRGeneration.set(OFTrue); |
52 | 0 | dcmEnableOtherDoubleVRGeneration.set(OFTrue); |
53 | 0 | dcmEnableOtherLongVRGeneration.set(OFTrue); |
54 | 0 | dcmEnableUniversalResourceIdentifierOrLocatorVRGeneration.set(OFTrue); |
55 | 0 | dcmEnableUnlimitedCharactersVRGeneration.set(OFTrue); |
56 | 0 | dcmEnableOther64bitVeryLongVRGeneration.set(OFTrue); |
57 | 0 | dcmEnableSigned64bitVeryLongVRGeneration.set(OFTrue); |
58 | 0 | dcmEnableUnsigned64bitVeryLongVRGeneration.set(OFTrue); |
59 | 0 | } |
60 | | |
61 | | void dcmDisableGenerationOfNewVRs() |
62 | 0 | { |
63 | 0 | dcmEnableUnknownVRGeneration.set(OFFalse); |
64 | 0 | dcmEnableUnlimitedTextVRGeneration.set(OFFalse); |
65 | 0 | dcmEnableOtherFloatVRGeneration.set(OFFalse); |
66 | 0 | dcmEnableOtherDoubleVRGeneration.set(OFFalse); |
67 | 0 | dcmEnableOtherLongVRGeneration.set(OFFalse); |
68 | 0 | dcmEnableUniversalResourceIdentifierOrLocatorVRGeneration.set(OFFalse); |
69 | 0 | dcmEnableUnlimitedCharactersVRGeneration.set(OFFalse); |
70 | 0 | dcmEnableOther64bitVeryLongVRGeneration.set(OFFalse); |
71 | 0 | dcmEnableSigned64bitVeryLongVRGeneration.set(OFFalse); |
72 | 0 | dcmEnableUnsigned64bitVeryLongVRGeneration.set(OFFalse); |
73 | 0 | } |
74 | | |
75 | | |
76 | | /* |
77 | | ** VR property table |
78 | | */ |
79 | | |
80 | | #define DCMVR_PROP_NONE 0x0000 |
81 | 0 | #define DCMVR_PROP_NONSTANDARD 0x0001 |
82 | 0 | #define DCMVR_PROP_INTERNAL 0x0002 |
83 | 0 | #define DCMVR_PROP_EXTENDEDLENGTHENCODING 0x0004 |
84 | 0 | #define DCMVR_PROP_ISASTRING 0x0008 |
85 | 0 | #define DCMVR_PROP_ISAFFECTEDBYCHARSET 0x0010 |
86 | 0 | #define DCMVR_PROP_ISLENGTHINCHAR 0x0020 |
87 | 0 | #define DCMVR_PROP_UNDEFINEDLENGTH 0x0040 |
88 | 0 | #define DCMVR_PROP_ISANUMBER 0x0080 |
89 | 0 | #define DCMVR_PROP_ISINTEGER 0x0100 |
90 | 0 | #define DCMVR_PROP_ISUNSIGNED 0x0200 |
91 | | |
92 | | struct DcmVREntry { |
93 | | DcmEVR vr; // Enumeration Value of Value representation |
94 | | const char* vrName; // Name of Value representation |
95 | | const OFString* delimiterChars; // Delimiter characters, switch to default charset |
96 | | size_t fValWidth; // Length of minimal unit, used for swapping |
97 | | int propertyFlags; // Normal, internal, non-standard VR, etc. |
98 | | Uint32 minValueLength; // Minimum length of a single value (bytes or characters) |
99 | | Uint32 maxValueLength; // Maximum length of a single value (bytes or characters) |
100 | | }; |
101 | | |
102 | | static const OFString noDelimiters; // none |
103 | | static const OFString bsDelimiter("\\"); // backslash |
104 | | static const OFString pnDelimiters("\\^="); // person name |
105 | | |
106 | | static const DcmVREntry DcmVRDict[] = { |
107 | | |
108 | | { EVR_AE, "AE", &noDelimiters, sizeof(char), DCMVR_PROP_ISASTRING, 0, 16 }, |
109 | | { EVR_AS, "AS", &noDelimiters, sizeof(char), DCMVR_PROP_ISASTRING, 4, 4 }, |
110 | | { EVR_AT, "AT", &noDelimiters, sizeof(Uint16), DCMVR_PROP_NONE, 4, 4 }, |
111 | | { EVR_CS, "CS", &noDelimiters, sizeof(char), DCMVR_PROP_ISASTRING, 0, 16 }, |
112 | | { EVR_DA, "DA", &noDelimiters, sizeof(char), DCMVR_PROP_ISASTRING, 8, 10 }, |
113 | | { EVR_DS, "DS", &noDelimiters, sizeof(char), DCMVR_PROP_ISASTRING | DCMVR_PROP_ISANUMBER, 0, 16 }, |
114 | | { EVR_DT, "DT", &noDelimiters, sizeof(char), DCMVR_PROP_ISASTRING, 0, 26 }, |
115 | | { EVR_FL, "FL", &noDelimiters, sizeof(Float32), DCMVR_PROP_ISANUMBER, 4, 4 }, |
116 | | { EVR_FD, "FD", &noDelimiters, sizeof(Float64), DCMVR_PROP_ISANUMBER, 8, 8 }, |
117 | | { EVR_IS, "IS", &noDelimiters, sizeof(char), DCMVR_PROP_ISASTRING | DCMVR_PROP_ISANUMBER | DCMVR_PROP_ISINTEGER, 0, 12 }, |
118 | | { EVR_LO, "LO", &bsDelimiter, sizeof(char), DCMVR_PROP_ISASTRING | DCMVR_PROP_ISAFFECTEDBYCHARSET | DCMVR_PROP_ISLENGTHINCHAR, 0, 64 }, |
119 | | { EVR_LT, "LT", &noDelimiters, sizeof(char), DCMVR_PROP_ISASTRING | DCMVR_PROP_ISAFFECTEDBYCHARSET | DCMVR_PROP_ISLENGTHINCHAR, 0, 10240 }, |
120 | | { EVR_OB, "OB", &noDelimiters, sizeof(Uint8), DCMVR_PROP_ISANUMBER | DCMVR_PROP_ISINTEGER | DCMVR_PROP_ISUNSIGNED | DCMVR_PROP_EXTENDEDLENGTHENCODING | DCMVR_PROP_UNDEFINEDLENGTH, 0, 4294967294U }, |
121 | | { EVR_OD, "OD", &noDelimiters, sizeof(Float64), DCMVR_PROP_ISANUMBER | DCMVR_PROP_EXTENDEDLENGTHENCODING | DCMVR_PROP_UNDEFINEDLENGTH, 0, 4294967288U }, |
122 | | { EVR_OF, "OF", &noDelimiters, sizeof(Float32), DCMVR_PROP_ISANUMBER | DCMVR_PROP_EXTENDEDLENGTHENCODING | DCMVR_PROP_UNDEFINEDLENGTH, 0, 4294967292U }, |
123 | | { EVR_OL, "OL", &noDelimiters, sizeof(Uint32), DCMVR_PROP_ISANUMBER | DCMVR_PROP_ISINTEGER | DCMVR_PROP_ISUNSIGNED | DCMVR_PROP_EXTENDEDLENGTHENCODING | DCMVR_PROP_UNDEFINEDLENGTH, 0, 4294967292U }, |
124 | | { EVR_OV, "OV", &noDelimiters, sizeof(Uint64), DCMVR_PROP_ISANUMBER | DCMVR_PROP_ISINTEGER | DCMVR_PROP_ISUNSIGNED | DCMVR_PROP_EXTENDEDLENGTHENCODING | DCMVR_PROP_UNDEFINEDLENGTH, 0, 4294967288U }, |
125 | | { EVR_OW, "OW", &noDelimiters, sizeof(Uint16), DCMVR_PROP_ISANUMBER | DCMVR_PROP_ISINTEGER | DCMVR_PROP_ISUNSIGNED | DCMVR_PROP_EXTENDEDLENGTHENCODING | DCMVR_PROP_UNDEFINEDLENGTH, 0, 4294967294U }, |
126 | | { EVR_PN, "PN", &pnDelimiters, sizeof(char), DCMVR_PROP_ISASTRING | DCMVR_PROP_ISAFFECTEDBYCHARSET | DCMVR_PROP_ISLENGTHINCHAR, 0, 64 }, |
127 | | { EVR_SH, "SH", &bsDelimiter, sizeof(char), DCMVR_PROP_ISASTRING | DCMVR_PROP_ISAFFECTEDBYCHARSET | DCMVR_PROP_ISLENGTHINCHAR, 0, 16 }, |
128 | | { EVR_SL, "SL", &noDelimiters, sizeof(Sint32), DCMVR_PROP_ISANUMBER | DCMVR_PROP_ISINTEGER, 4, 4 }, |
129 | | { EVR_SQ, "SQ", &noDelimiters, 0, DCMVR_PROP_EXTENDEDLENGTHENCODING | DCMVR_PROP_UNDEFINEDLENGTH, 0, 4294967294U }, |
130 | | { EVR_SS, "SS", &noDelimiters, sizeof(Sint16), DCMVR_PROP_ISANUMBER | DCMVR_PROP_ISINTEGER, 2, 2 }, |
131 | | { EVR_ST, "ST", &noDelimiters, sizeof(char), DCMVR_PROP_ISASTRING | DCMVR_PROP_ISAFFECTEDBYCHARSET | DCMVR_PROP_ISLENGTHINCHAR, 0, 1024 }, |
132 | | { EVR_SV, "SV", &noDelimiters, sizeof(Sint64), DCMVR_PROP_ISANUMBER | DCMVR_PROP_ISINTEGER | DCMVR_PROP_EXTENDEDLENGTHENCODING, 8, 8 }, |
133 | | { EVR_TM, "TM", &noDelimiters, sizeof(char), DCMVR_PROP_ISASTRING, 0, 16 }, |
134 | | { EVR_UC, "UC", &bsDelimiter, sizeof(char), DCMVR_PROP_ISASTRING | DCMVR_PROP_EXTENDEDLENGTHENCODING | DCMVR_PROP_ISAFFECTEDBYCHARSET, 0, 4294967294U }, |
135 | | { EVR_UI, "UI", &noDelimiters, sizeof(char), DCMVR_PROP_ISASTRING, 0, 64 }, |
136 | | { EVR_UL, "UL", &noDelimiters, sizeof(Uint32), DCMVR_PROP_ISANUMBER | DCMVR_PROP_ISINTEGER | DCMVR_PROP_ISUNSIGNED, 4, 4 }, |
137 | | { EVR_UR, "UR", &noDelimiters, sizeof(char), DCMVR_PROP_ISASTRING | DCMVR_PROP_EXTENDEDLENGTHENCODING, 0, 4294967294U }, |
138 | | { EVR_US, "US", &noDelimiters, sizeof(Uint16), DCMVR_PROP_ISANUMBER | DCMVR_PROP_ISINTEGER | DCMVR_PROP_ISUNSIGNED, 2, 2 }, |
139 | | { EVR_UT, "UT", &noDelimiters, sizeof(char), DCMVR_PROP_ISASTRING | DCMVR_PROP_EXTENDEDLENGTHENCODING | DCMVR_PROP_ISAFFECTEDBYCHARSET, 0, 4294967294U }, |
140 | | { EVR_UV, "UV", &noDelimiters, sizeof(Uint64), DCMVR_PROP_ISANUMBER | DCMVR_PROP_ISINTEGER | DCMVR_PROP_ISUNSIGNED | DCMVR_PROP_EXTENDEDLENGTHENCODING, 8, 8 }, |
141 | | { EVR_ox, "ox", &noDelimiters, sizeof(Uint8), DCMVR_PROP_NONSTANDARD | DCMVR_PROP_EXTENDEDLENGTHENCODING | DCMVR_PROP_UNDEFINEDLENGTH, 0, 4294967294U }, |
142 | | { EVR_px, "px", &noDelimiters, sizeof(Uint8), DCMVR_PROP_NONSTANDARD | DCMVR_PROP_EXTENDEDLENGTHENCODING | DCMVR_PROP_UNDEFINEDLENGTH, 0, 4294967294U }, |
143 | | { EVR_xs, "xs", &noDelimiters, sizeof(Uint16), DCMVR_PROP_NONSTANDARD, 2, 2 }, |
144 | | { EVR_lt, "lt", &noDelimiters, sizeof(Uint16), DCMVR_PROP_NONSTANDARD | DCMVR_PROP_EXTENDEDLENGTHENCODING, 0, 4294967294U }, |
145 | | { EVR_na, "na", &noDelimiters, 0, DCMVR_PROP_NONSTANDARD, 0, 0 }, |
146 | | { EVR_up, "up", &noDelimiters, sizeof(Uint32), DCMVR_PROP_NONSTANDARD, 4, 4 }, |
147 | | |
148 | | /* unique prefixes have been "invented" for the following internal VRs */ |
149 | | { EVR_item, "it_EVR_item", &noDelimiters, 0, DCMVR_PROP_NONSTANDARD | DCMVR_PROP_INTERNAL, 0, 0 }, |
150 | | { EVR_metainfo, "mi_EVR_metainfo", &noDelimiters, 0, DCMVR_PROP_NONSTANDARD | DCMVR_PROP_INTERNAL, 0, 0 }, |
151 | | { EVR_dataset, "ds_EVR_dataset", &noDelimiters, 0, DCMVR_PROP_NONSTANDARD | DCMVR_PROP_INTERNAL, 0, 0 }, |
152 | | { EVR_fileFormat, "ff_EVR_fileFormat", &noDelimiters, 0, DCMVR_PROP_NONSTANDARD | DCMVR_PROP_INTERNAL, 0, 0 }, |
153 | | { EVR_dicomDir, "dd_EVR_dicomDir", &noDelimiters, 0, DCMVR_PROP_NONSTANDARD | DCMVR_PROP_INTERNAL, 0, 0 }, |
154 | | { EVR_dirRecord, "dr_EVR_dirRecord", &noDelimiters, 0, DCMVR_PROP_NONSTANDARD | DCMVR_PROP_INTERNAL, 0, 0 }, |
155 | | |
156 | | { EVR_pixelSQ, "ps_EVR_pixelSQ", &noDelimiters, sizeof(Uint8), DCMVR_PROP_NONSTANDARD | DCMVR_PROP_INTERNAL, 0, DCM_UndefinedLength }, |
157 | | /* Moved from internal use to non-standard only: necessary to distinguish from "normal" OB */ |
158 | | { EVR_pixelItem, "pi", &noDelimiters, sizeof(Uint8), DCMVR_PROP_NONSTANDARD, 0, DCM_UndefinedLength }, |
159 | | |
160 | | /* EVR_UNKNOWN (i.e. "future" VRs) should be mapped to UN or OB */ |
161 | | { EVR_UNKNOWN, "??", &noDelimiters, sizeof(Uint8), DCMVR_PROP_NONSTANDARD | DCMVR_PROP_INTERNAL | DCMVR_PROP_EXTENDEDLENGTHENCODING | DCMVR_PROP_UNDEFINEDLENGTH, 0, DCM_UndefinedLength }, |
162 | | |
163 | | /* Unknown Value Representation */ |
164 | | { EVR_UN, "UN", &noDelimiters, sizeof(Uint8), DCMVR_PROP_EXTENDEDLENGTHENCODING | DCMVR_PROP_UNDEFINEDLENGTH, 0, 4294967294U }, |
165 | | |
166 | | /* Pixel Data - only used in ident() */ |
167 | | { EVR_PixelData, "PixelData", &noDelimiters, 0, DCMVR_PROP_INTERNAL, 0, DCM_UndefinedLength }, |
168 | | /* Overlay Data - only used in ident() */ |
169 | | { EVR_OverlayData, "OverlayData", &noDelimiters, 0, DCMVR_PROP_INTERNAL, 0, DCM_UndefinedLength }, |
170 | | |
171 | | /* unknown (probably invalid) VR, we assume no extended length coding */ |
172 | | { EVR_UNKNOWN2B, "??", &noDelimiters, sizeof(Uint8), DCMVR_PROP_NONSTANDARD | DCMVR_PROP_INTERNAL, 0, DCM_UndefinedLength }, |
173 | | |
174 | | /* invalid VR - only used internally, e.g. to abort parsing a data set */ |
175 | | { EVR_invalid, "--", &noDelimiters, 0, DCMVR_PROP_NONSTANDARD | DCMVR_PROP_INTERNAL, 0, DCM_UndefinedLength } |
176 | | }; |
177 | | |
178 | | static const int DcmVRDict_DIM = OFstatic_cast(int, sizeof(DcmVRDict) / sizeof(DcmVREntry)); |
179 | | |
180 | | |
181 | | /* |
182 | | ** Check the consistency of the DcmVRDict |
183 | | */ |
184 | | |
185 | | #ifdef DEBUG |
186 | | |
187 | | #include "dcmtk/ofstd/ofstream.h" |
188 | | |
189 | | class DcmVRDict_checker { |
190 | | private: |
191 | | int error_found; |
192 | | public: |
193 | | DcmVRDict_checker(); |
194 | | }; |
195 | | |
196 | | DcmVRDict_checker::DcmVRDict_checker() |
197 | | : error_found(OFFalse) |
198 | | { |
199 | | for (int i = 0; i < DcmVRDict_DIM; i++) { |
200 | | if (DcmVRDict[i].vr != i) { |
201 | | error_found = OFTrue; |
202 | | DCMDATA_FATAL("DcmVRDict: Internal ERROR: inconsistent indexing: " << DcmVRDict[i].vrName); |
203 | | abort(); |
204 | | } |
205 | | } |
206 | | } |
207 | | |
208 | | const DcmVRDict_checker DcmVRDict_startup_check(); |
209 | | |
210 | | #endif |
211 | | |
212 | | /* |
213 | | ** DcmVR member functions |
214 | | */ |
215 | | |
216 | | void |
217 | | DcmVR::setVR(DcmEVR evr) |
218 | 16 | { |
219 | 16 | if ((OFstatic_cast(int, evr) >= 0) && (OFstatic_cast(int, evr) < DcmVRDict_DIM)) { |
220 | 16 | vr = evr; |
221 | 16 | } else { |
222 | 0 | vr = EVR_invalid; |
223 | 0 | } |
224 | 16 | } |
225 | | |
226 | | void |
227 | | DcmVR::setVR(const char* vrName) |
228 | 0 | { |
229 | 0 | vr = EVR_invalid; /* default */ |
230 | | /* Make sure that the passed character string is not empty */ |
231 | 0 | if ((vrName != NULL) && (*vrName != '\0')) |
232 | 0 | { |
233 | | /* Extract the first two characters from the passed string */ |
234 | 0 | const char c1 = *vrName; |
235 | 0 | const char c2 = *(vrName + 1); |
236 | | |
237 | | /* Workaround: There have been reports of systems transmitting |
238 | | * illegal VR strings in explicit VR (i.e. "??") without using |
239 | | * extended length fields. |
240 | | */ |
241 | 0 | if ((c1 == '?') && (c2 == '?')) |
242 | 0 | { |
243 | | /* We assume a 2-byte length field. */ |
244 | 0 | vr = EVR_UNKNOWN2B; |
245 | 0 | } else { |
246 | 0 | OFBool found = OFFalse; |
247 | 0 | for (int i = 0; i < DcmVRDict_DIM; i++) |
248 | 0 | { |
249 | | /* We only compare the first two characters of the passed string |
250 | | * and never accept a VR that is labeled for internal use only. |
251 | | */ |
252 | 0 | if ((DcmVRDict[i].vrName[0] == c1) && (DcmVRDict[i].vrName[1] == c2) && |
253 | 0 | ((DcmVRDict[i].propertyFlags & DCMVR_PROP_INTERNAL) == 0)) |
254 | 0 | { |
255 | 0 | vr = DcmVRDict[i].vr; |
256 | 0 | found = OFTrue; |
257 | 0 | break; |
258 | 0 | } |
259 | 0 | } |
260 | 0 | if (!found) |
261 | 0 | { |
262 | | /* More workarounds: The VR is unknown (or not yet supported). |
263 | | * The DICOM committee has announced that all future VRs will |
264 | | * use extended length. Therefore, we treat all unknown VR |
265 | | * strings consisting of uppercase letters as "real" future VRs |
266 | | * (and thus assume extended length). |
267 | | * For other unknown VR strings that use characters in a range |
268 | | * of 32 to 127, we assume a 2-byte length field. |
269 | | * All other VR strings are treated as invalid VRs (default). |
270 | | */ |
271 | 0 | if ((c1 >= 'A') && (c1 <= 'Z') && (c2 >= 'A') && (c2 <= 'Z')) |
272 | 0 | { |
273 | | /* Possible future VR, we assume a 4-byte length field. */ |
274 | 0 | vr = EVR_UNKNOWN; |
275 | 0 | } |
276 | 0 | else if ((c1 >= 32) && (c1 <= 127) && (c2 >= 32) && (c2 <= 127)) |
277 | 0 | { |
278 | | /* Non-standard VR, we assume a 2-byte length field. */ |
279 | 0 | vr = EVR_UNKNOWN2B; |
280 | 0 | } |
281 | 0 | } |
282 | 0 | } |
283 | 0 | } |
284 | 0 | } |
285 | | |
286 | | DcmEVR |
287 | | DcmVR::getValidEVR() const |
288 | 0 | { |
289 | 0 | DcmEVR evr = EVR_UNKNOWN; |
290 | |
|
291 | 0 | if (isStandard()) { |
292 | 0 | evr = vr; |
293 | 0 | } else { |
294 | 0 | switch (vr) { |
295 | 0 | case EVR_up: |
296 | 0 | evr = EVR_UL; |
297 | 0 | break; |
298 | 0 | case EVR_xs: |
299 | 0 | evr = EVR_US; |
300 | 0 | break; |
301 | 0 | case EVR_lt: |
302 | 0 | evr = EVR_OW; |
303 | 0 | break; |
304 | 0 | case EVR_ox: |
305 | 0 | case EVR_px: |
306 | 0 | case EVR_pixelSQ: |
307 | 0 | evr = EVR_OB; |
308 | 0 | break; |
309 | 0 | default: |
310 | 0 | evr = EVR_UN; /* handle as Unknown VR */ |
311 | 0 | break; |
312 | 0 | } |
313 | 0 | } |
314 | | |
315 | | /* |
316 | | ** If the generation of post-1993 VRs is not globally enabled then use OB instead. |
317 | | ** We may not want to generate these "new" VRs if other software cannot handle it. |
318 | | */ |
319 | 0 | const DcmEVR oldVR = evr; |
320 | 0 | switch (evr) { |
321 | 0 | case EVR_UN: |
322 | 0 | if (!dcmEnableUnknownVRGeneration.get()) |
323 | 0 | evr = EVR_OB; /* handle UN as if OB */ |
324 | 0 | break; |
325 | 0 | case EVR_UT: |
326 | 0 | if (!dcmEnableUnlimitedTextVRGeneration.get()) |
327 | 0 | { |
328 | 0 | if (dcmEnableUnknownVRGeneration.get()) |
329 | 0 | evr = EVR_UN; /* handle UT as if UN */ |
330 | 0 | else |
331 | 0 | evr = EVR_OB; /* handle UT as if OB */ |
332 | 0 | } |
333 | 0 | break; |
334 | 0 | case EVR_OF: |
335 | 0 | if (!dcmEnableOtherFloatVRGeneration.get()) |
336 | 0 | { |
337 | 0 | if (dcmEnableUnknownVRGeneration.get()) |
338 | 0 | evr = EVR_UN; /* handle OF as if UN */ |
339 | 0 | else |
340 | 0 | evr = EVR_OB; /* handle OF as if OB */ |
341 | 0 | } |
342 | 0 | break; |
343 | 0 | case EVR_OD: |
344 | 0 | if (!dcmEnableOtherDoubleVRGeneration.get()) |
345 | 0 | { |
346 | 0 | if (dcmEnableUnknownVRGeneration.get()) |
347 | 0 | evr = EVR_UN; /* handle OD as if UN */ |
348 | 0 | else |
349 | 0 | evr = EVR_OB; /* handle OD as if OB */ |
350 | 0 | } |
351 | 0 | break; |
352 | 0 | case EVR_OL: |
353 | 0 | if (!dcmEnableOtherLongVRGeneration.get()) |
354 | 0 | { |
355 | 0 | if (dcmEnableUnknownVRGeneration.get()) |
356 | 0 | evr = EVR_UN; /* handle OL as if UN */ |
357 | 0 | else |
358 | 0 | evr = EVR_OB; /* handle OL as if OB */ |
359 | 0 | } |
360 | 0 | break; |
361 | 0 | case EVR_UR: |
362 | 0 | if (!dcmEnableUniversalResourceIdentifierOrLocatorVRGeneration.get()) |
363 | 0 | { |
364 | 0 | if (dcmEnableUnlimitedTextVRGeneration.get()) |
365 | 0 | evr = EVR_UT; /* handle UR as if UT */ |
366 | 0 | else if (dcmEnableUnknownVRGeneration.get()) |
367 | 0 | evr = EVR_UN; /* handle UR as if UN */ |
368 | 0 | else |
369 | 0 | evr = EVR_OB; /* handle UR as if OB */ |
370 | 0 | } |
371 | 0 | break; |
372 | 0 | case EVR_UC: |
373 | 0 | if (!dcmEnableUnlimitedCharactersVRGeneration.get()) |
374 | 0 | { |
375 | 0 | if (dcmEnableUnknownVRGeneration.get()) |
376 | 0 | evr = EVR_UN; /* handle UC as if UN */ |
377 | 0 | else |
378 | 0 | evr = EVR_OB; /* handle UC as if OB */ |
379 | 0 | } |
380 | 0 | break; |
381 | 0 | case EVR_OV: |
382 | 0 | if (!dcmEnableOther64bitVeryLongVRGeneration.get()) |
383 | 0 | { |
384 | 0 | if (dcmEnableUnknownVRGeneration.get()) |
385 | 0 | evr = EVR_UN; /* handle OV as if UN */ |
386 | 0 | else |
387 | 0 | evr = EVR_OB; /* handle OV as if OB */ |
388 | 0 | } |
389 | 0 | break; |
390 | 0 | case EVR_SV: |
391 | 0 | if (!dcmEnableSigned64bitVeryLongVRGeneration.get()) |
392 | 0 | { |
393 | 0 | if (dcmEnableUnknownVRGeneration.get()) |
394 | 0 | evr = EVR_UN; /* handle SV as if UN */ |
395 | 0 | else |
396 | 0 | evr = EVR_OB; /* handle SV as if OB */ |
397 | 0 | } |
398 | 0 | break; |
399 | 0 | case EVR_UV: |
400 | 0 | if (!dcmEnableUnsigned64bitVeryLongVRGeneration.get()) |
401 | 0 | { |
402 | 0 | if (dcmEnableUnknownVRGeneration.get()) |
403 | 0 | evr = EVR_UN; /* handle UV as if UN */ |
404 | 0 | else |
405 | 0 | evr = EVR_OB; /* handle UV as if OB */ |
406 | 0 | } |
407 | 0 | break; |
408 | 0 | default: |
409 | | /* in all other cases, do nothing */ |
410 | 0 | break; |
411 | 0 | } |
412 | 0 | if (oldVR != evr) |
413 | 0 | { |
414 | 0 | DCMDATA_TRACE("DcmVR::getValidEVR() VR=\"" << DcmVR(oldVR).getVRName() |
415 | 0 | << "\" replaced by \"" << DcmVR(evr).getVRName() << "\" since support is disabled"); |
416 | 0 | } |
417 | |
|
418 | 0 | return evr; |
419 | 0 | } |
420 | | |
421 | | size_t |
422 | | DcmVR::getValueWidth(void) const |
423 | 0 | { |
424 | 0 | return DcmVRDict[vr].fValWidth; |
425 | 0 | } |
426 | | |
427 | | |
428 | | const char* |
429 | | DcmVR::getVRName() const |
430 | 0 | { |
431 | 0 | return DcmVRDict[vr].vrName; |
432 | 0 | } |
433 | | |
434 | | const char* |
435 | | DcmVR::getValidVRName() const |
436 | 0 | { |
437 | 0 | return DcmVR(getValidEVR()).getVRName(); |
438 | 0 | } |
439 | | |
440 | | OFBool |
441 | | DcmVR::isInvalid() const |
442 | 0 | { |
443 | 0 | return (vr == EVR_invalid); |
444 | 0 | } |
445 | | |
446 | | OFBool |
447 | | DcmVR::isUnknown() const |
448 | 0 | { |
449 | 0 | return (vr == EVR_UNKNOWN) || (vr == EVR_UNKNOWN2B); |
450 | 0 | } |
451 | | |
452 | | OFBool |
453 | | DcmVR::isStandard() const |
454 | 0 | { |
455 | 0 | return (DcmVRDict[vr].propertyFlags & DCMVR_PROP_NONSTANDARD) ? OFFalse : OFTrue; |
456 | 0 | } |
457 | | |
458 | | OFBool |
459 | | DcmVR::isForInternalUseOnly() const |
460 | 0 | { |
461 | 0 | return (DcmVRDict[vr].propertyFlags & DCMVR_PROP_INTERNAL) ? OFTrue : OFFalse; |
462 | 0 | } |
463 | | |
464 | | /* returns true if VR represents a string */ |
465 | | OFBool |
466 | | DcmVR::isaString() const |
467 | 0 | { |
468 | 0 | return (DcmVRDict[vr].propertyFlags & DCMVR_PROP_ISASTRING) ? OFTrue : OFFalse; |
469 | 0 | } |
470 | | |
471 | | /* returns true if VR represents a number */ |
472 | | OFBool |
473 | | DcmVR::isaNumber() const |
474 | 0 | { |
475 | 0 | return (DcmVRDict[vr].propertyFlags & DCMVR_PROP_ISANUMBER) ? OFTrue : OFFalse; |
476 | 0 | } |
477 | | |
478 | | /* returns true if VR represents an integer number */ |
479 | | OFBool |
480 | | DcmVR::isInteger() const |
481 | 0 | { |
482 | 0 | return (DcmVRDict[vr].propertyFlags & DCMVR_PROP_ISINTEGER) ? OFTrue : OFFalse; |
483 | 0 | } |
484 | | |
485 | | /* returns true if VR represents an unsigned number */ |
486 | | OFBool |
487 | | DcmVR::isUnsigned() const |
488 | 0 | { |
489 | 0 | return (DcmVRDict[vr].propertyFlags & DCMVR_PROP_ISUNSIGNED) ? OFTrue : OFFalse; |
490 | 0 | } |
491 | | |
492 | | /* |
493 | | * returns true if VR uses an extended length encoding |
494 | | * for explicit transfer syntaxes |
495 | | */ |
496 | | OFBool |
497 | | DcmVR::usesExtendedLengthEncoding() const |
498 | 0 | { |
499 | 0 | return (DcmVRDict[vr].propertyFlags & DCMVR_PROP_EXTENDEDLENGTHENCODING) ? OFTrue : OFFalse; |
500 | 0 | } |
501 | | |
502 | | /* returns true if VR supports undefined length */ |
503 | | OFBool |
504 | | DcmVR::supportsUndefinedLength() const |
505 | 0 | { |
506 | 0 | return (DcmVRDict[vr].propertyFlags & DCMVR_PROP_UNDEFINEDLENGTH) ? OFTrue : OFFalse; |
507 | 0 | } |
508 | | |
509 | | Uint32 |
510 | | DcmVR::getMinValueLength() const |
511 | 0 | { |
512 | 0 | return (DcmVRDict[vr].minValueLength); |
513 | 0 | } |
514 | | |
515 | | Uint32 |
516 | | DcmVR::getMaxValueLength() const |
517 | 0 | { |
518 | 0 | return (DcmVRDict[vr].maxValueLength); |
519 | 0 | } |
520 | | |
521 | | /* returns true if the VR is equivalent */ |
522 | | OFBool |
523 | | DcmVR::isEquivalent(const DcmVR& avr) const |
524 | 0 | { |
525 | 0 | const DcmEVR evr = avr.getEVR(); |
526 | 0 | if (vr == evr) return OFTrue; |
527 | | |
528 | 0 | OFBool result = OFFalse; |
529 | 0 | switch (vr) |
530 | 0 | { |
531 | 0 | case EVR_ox: |
532 | 0 | case EVR_px: |
533 | 0 | result = (evr == EVR_OB || evr == EVR_OW); |
534 | 0 | break; |
535 | 0 | case EVR_lt: |
536 | 0 | result = (evr == EVR_OW || evr == EVR_US || evr == EVR_SS); |
537 | 0 | break; |
538 | 0 | case EVR_OB: |
539 | 0 | result = (evr == EVR_ox || evr == EVR_px); |
540 | 0 | break; |
541 | 0 | case EVR_OW: |
542 | 0 | result = (evr == EVR_ox || evr == EVR_px || evr == EVR_lt); |
543 | 0 | break; |
544 | 0 | case EVR_up: |
545 | 0 | result = (evr == EVR_UL); |
546 | 0 | break; |
547 | 0 | case EVR_UL: |
548 | 0 | result = (evr == EVR_up); |
549 | 0 | break; |
550 | 0 | case EVR_xs: |
551 | 0 | result = (evr == EVR_SS || evr == EVR_US); |
552 | 0 | break; |
553 | 0 | case EVR_SS: |
554 | 0 | case EVR_US: |
555 | 0 | result = (evr == EVR_xs || evr == EVR_lt); |
556 | 0 | break; |
557 | 0 | default: |
558 | 0 | break; |
559 | 0 | } |
560 | 0 | return result; |
561 | 0 | } |
562 | | |
563 | | OFBool |
564 | | DcmVR::isAffectedBySpecificCharacterSet() const |
565 | 0 | { |
566 | 0 | return (DcmVRDict[vr].propertyFlags & DCMVR_PROP_ISAFFECTEDBYCHARSET) ? OFTrue : OFFalse; |
567 | 0 | } |
568 | | |
569 | | const OFString& |
570 | | DcmVR::getDelimiterChars() const |
571 | 0 | { |
572 | 0 | return *DcmVRDict[vr].delimiterChars; |
573 | 0 | } |
574 | | |
575 | | /* returns true if VR length is in char */ |
576 | | OFBool |
577 | | DcmVR::isLengthInChar() const |
578 | 0 | { |
579 | 0 | return (DcmVRDict[vr].propertyFlags & DCMVR_PROP_ISLENGTHINCHAR) ? OFTrue : OFFalse; |
580 | 0 | } |