/work/dcmtk-install/include/dcmtk/dcmdata/dcobject.h
Line | Count | Source |
1 | | /* |
2 | | * |
3 | | * Copyright (C) 1994-2026, 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 |
17 | | * |
18 | | * Purpose: |
19 | | * This file contains the interface to routines which provide |
20 | | * DICOM object encoding/decoding, search and lookup facilities. |
21 | | * |
22 | | */ |
23 | | |
24 | | |
25 | | #ifndef DCOBJECT_H |
26 | | #define DCOBJECT_H |
27 | | |
28 | | #include "dcmtk/config/osconfig.h" /* make sure OS specific configuration is included first */ |
29 | | |
30 | | #include "dcmtk/ofstd/ofglobal.h" |
31 | | #include "dcmtk/dcmdata/dcerror.h" |
32 | | #include "dcmtk/dcmdata/dcxfer.h" |
33 | | #include "dcmtk/dcmdata/dctag.h" |
34 | | #include "dcmtk/dcmdata/dcstack.h" |
35 | | |
36 | | |
37 | | // forward declarations |
38 | | class DcmItem; |
39 | | class DcmJsonFormat; |
40 | | class DcmOutputStream; |
41 | | class DcmInputStream; |
42 | | class DcmWriteCache; |
43 | | class DcmSpecificCharacterSet; |
44 | | |
45 | | // include this file in doxygen documentation |
46 | | |
47 | | /** @file dcobject.h |
48 | | * @brief interface to DICOM object/dataset handling |
49 | | */ |
50 | | |
51 | | // Undefined Length Identifier now defined in dctypes.h |
52 | | |
53 | | // Default maximum sequence nesting depth (can be overridden at compile time). |
54 | | // Must be in the range [1, 2147483647]. |
55 | | #ifndef DCMTK_MAX_SEQUENCE_NESTING |
56 | | #define DCMTK_MAX_SEQUENCE_NESTING 64 |
57 | | #endif |
58 | | #if DCMTK_MAX_SEQUENCE_NESTING < 1 |
59 | | #error "DCMTK_MAX_SEQUENCE_NESTING must be >= 1" |
60 | | #endif |
61 | | #if DCMTK_MAX_SEQUENCE_NESTING > 2147483647 |
62 | | #error "DCMTK_MAX_SEQUENCE_NESTING must be <= 2147483647" |
63 | | #endif |
64 | | |
65 | | // Maximum number of read bytes for a Value Element |
66 | | const Uint32 DCM_MaxReadLength = 4096; |
67 | | |
68 | | // Maximum length of tag and length in a DICOM element |
69 | | const Uint32 DCM_TagInfoLength = 12; |
70 | | |
71 | | // Optimum line length if not all data printed |
72 | | const Uint32 DCM_OptPrintLineLength = 70; |
73 | | |
74 | | // Optimum value length if not all data printed |
75 | | const Uint32 DCM_OptPrintValueLength = 40; |
76 | | |
77 | | // Optimum attribute name length (for tree output) |
78 | | const Uint32 DCM_OptPrintAttributeNameLength = 35; |
79 | | |
80 | | /** This flags defines whether automatic correction should be applied to input |
81 | | * data (e.g.\ stripping of padding blanks, removal of blanks in UIDs, etc). |
82 | | * Default is enabled. |
83 | | */ |
84 | | extern DCMTK_DCMDATA_EXPORT OFGlobal<OFBool> dcmEnableAutomaticInputDataCorrection; /* default OFTrue */ |
85 | | |
86 | | /** This flag defines the handling of illegal odd-length attributes: If flag is |
87 | | * true, odd lengths are respected (i.e.\ an odd number of bytes is read from |
88 | | * the input stream.) After successful reading, padding to even number of bytes |
89 | | * is enforced by adding a zero pad byte if dcmEnableAutomaticInputDataCorrection |
90 | | * is true. Otherwise the odd number of bytes remains as read. |
91 | | * |
92 | | * If flag is false, old (pre DCMTK 3.5.2) behaviour applies: The length field |
93 | | * implicitly incremented and an even number of bytes is read from the stream. |
94 | | */ |
95 | | extern DCMTK_DCMDATA_EXPORT OFGlobal<OFBool> dcmAcceptOddAttributeLength; /* default OFTrue */ |
96 | | |
97 | | /** This flag defines how UN attributes with undefined length are treated |
98 | | * by the parser when reading. The default is to expect the content of the |
99 | | * UN element (up to and including the sequence delimitation item) |
100 | | * to be encoded in Implicit VR Little Endian, as described in CP 246. |
101 | | * DCMTK expects the attribute to be encoded like a DICOM sequence, i.e. |
102 | | * the content of each item is parsed as a DICOM dataset. |
103 | | * If the flag is disabled old (pre DCMTK 3.5.4) behaviour applies: The |
104 | | * attribute is treated as if it was an Explicit VR SQ element. |
105 | | * |
106 | | * Note that the flag only affects the read behaviour but not the write |
107 | | * behaviour - DCMTK will never write UN elements with undefined length. |
108 | | */ |
109 | | extern DCMTK_DCMDATA_EXPORT OFGlobal<OFBool> dcmEnableCP246Support; /* default OFTrue */ |
110 | | |
111 | | /** DCMTK releases up to 3.5.3 created a non-conforming byte stream |
112 | | * as input to the MAC algorithm when creating or verifying digital signatures |
113 | | * including compressed pixel data (i.e.\ signatures including attribute |
114 | | * (7FE0,0010) in an encapsulated transfer syntax). This has been fixed |
115 | | * in DCMTK 3.5.4, but this flag allows to revert to the old behavior |
116 | | * in order to create or verify signatures that are compatible with older |
117 | | * releases. Default is "off" (OFFalse). |
118 | | */ |
119 | | extern DCMTK_DCMDATA_EXPORT OFGlobal<OFBool> dcmEnableOldSignatureFormat; /* default OFFalse */ |
120 | | |
121 | | /** This flag defines whether the transfer syntax for uncompressed datasets |
122 | | * is detected automatically. The automatic detection has been introduced |
123 | | * since there are (incorrectly encoded) DICOM dataset stored with a |
124 | | * different transfer syntax than specified in the meta header. |
125 | | */ |
126 | | extern DCMTK_DCMDATA_EXPORT OFGlobal<OFBool> dcmAutoDetectDatasetXfer; /* default OFFalse */ |
127 | | |
128 | | /** This flag defines how non-standard VRs are treated by the parser when |
129 | | * reading. The default is to treat data element with non-standard VR as |
130 | | * unknown. If this flag is enabled, the parser will try to read the data |
131 | | * element with Implicit VR Little Endian transfer syntax. |
132 | | */ |
133 | | extern DCMTK_DCMDATA_EXPORT OFGlobal<OFBool> dcmAcceptUnexpectedImplicitEncoding; /* default OFFalse */ |
134 | | |
135 | | /** This flag defines how the element's VR is treated by the parser when |
136 | | * reading from a dataset with explicit VR encoding. By default, the |
137 | | * VR from the dataset is used. If this flag is enabled and the VR of the |
138 | | * tag is defined in the data dictionary, the parser will use the VR from |
139 | | * the data dictionary (and ignore the one from the dataset). This flag is, |
140 | | * therefore, useful for reading incorrectly encoded DICOM datasets. |
141 | | */ |
142 | | extern DCMTK_DCMDATA_EXPORT OFGlobal<OFBool> dcmPreferVRFromDataDictionary; /* default OFFalse */ |
143 | | |
144 | | /** This flag defines how the element's length field is interpreted when reading |
145 | | * from a dataset with explicit VR encoding and the data dictionary doesn't |
146 | | * agree with the VR from the dataset. By default, the length field is assumed |
147 | | * to match the size of the VR in the dataset. If this flag is enabled and the |
148 | | * tag is defined in the data dictionary, the parser will use the size for the |
149 | | * VR from the data dictionary (and ignore the one from the dataset). This flag |
150 | | * is, therefore, useful for reading incorrectly encoded DICOM datasets. |
151 | | */ |
152 | | extern DCMTK_DCMDATA_EXPORT OFGlobal<OFBool> dcmPreferLengthFieldSizeFromDataDictionary; /* default OFFalse */ |
153 | | |
154 | | /** This flag indicates, whether private attributes with implicit transfer |
155 | | * syntax having a maximum length should be handled as sequences (ignoring |
156 | | * any dictionary entries for that tag). This can happen, if for example |
157 | | * a private creator element is illegally inserted with VR SQ |
158 | | * (undefined length and implicit coding). The parser usually would then |
159 | | * try to parse the element with VR=LO (private creator) with maximum |
160 | | * length, which would lead to an error. The default behaviour is to |
161 | | * rely on the dictionary. |
162 | | */ |
163 | | extern DCMTK_DCMDATA_EXPORT OFGlobal<OFBool> dcmReadImplPrivAttribMaxLengthAsSQ; /* default OFFalse */ |
164 | | |
165 | | /** This flag indicates, whether parsing errors during reading |
166 | | * should be ignored, i.e.\ whether the parser should try to recover and |
167 | | * parse the rest of the stream. |
168 | | * This flag does not work for all parsing errors (at this time) |
169 | | * making sense but was introduced afterwards. |
170 | | */ |
171 | | extern DCMTK_DCMDATA_EXPORT OFGlobal<OFBool> dcmIgnoreParsingErrors; /* default OFFalse */ |
172 | | |
173 | | /** This flag indicates, whether parsing should stop after a certain |
174 | | * element in the stream was parsed. This is especially useful for |
175 | | * datasets containing garbage at the end, usually after the Pixel |
176 | | * Data attribute. To prevent the parser for "stumbling" over that |
177 | | * garbage, it is possible to tell the parser to stop after a |
178 | | * specific element. The flag is only sensitive to elements on |
179 | | * dataset level, i.e. inside sequence any occurrence of the specified |
180 | | * tag is ignored. Caution: Note that if Pixel Data is chosen |
181 | | * as stop element, any attributes behind will not be parsed, e. g. |
182 | | * any digital signature attributes coming after. |
183 | | * Default is (0xffff,0xffff), which means that the feature is |
184 | | * disabled. |
185 | | */ |
186 | | extern DCMTK_DCMDATA_EXPORT OFGlobal<DcmTagKey> dcmStopParsingAfterElement; /* default OFTrue */ |
187 | | |
188 | | /** This flag influences behaviour when writing a dataset with items |
189 | | * and sequences set to be encoded with explicit length. It is possible |
190 | | * that the content of a sequence (or item) has an encoded length greater |
191 | | * than the maximum 32-bit value that can be written to the sequence (item) |
192 | | * length field. If this flag is enabled (OFTrue) then the encoding of the |
193 | | * very sequence (item) is switched to undefined length encoding. Any |
194 | | * contained items (sequences) will be encoded explicitly if possible. |
195 | | * Default is OFTrue, i.e. encoding is switched to implicit if maximum |
196 | | * size of length field is exceeded. |
197 | | */ |
198 | | extern DCMTK_DCMDATA_EXPORT OFGlobal<OFBool> dcmWriteOversizedSeqsAndItemsUndefined; /* default OFTrue */ |
199 | | |
200 | | /** This flag allows for ignoring the value of (0002,0000) File Meta Information |
201 | | * Group Length which is useful in cases where this value is incorrect. If the |
202 | | * header length is ignored, the behavior is identical to the case when no value |
203 | | * is available (i.e. all elements are read as long as the group number is 0x0002). |
204 | | */ |
205 | | extern DCMTK_DCMDATA_EXPORT OFGlobal<OFBool> dcmIgnoreFileMetaInformationGroupLength; /* default OFFalse */ |
206 | | |
207 | | /** This flag enables the replacement of a wrong delimitation item at the end of |
208 | | * a sequence or item. This is because there are incorrect systems that write |
209 | | * a Sequence Delimitation Item (fffe,e0dd) at the end of an item or an Item |
210 | | * Delimitation Item (fffe,e00d) at the end of a sequence. By default, no |
211 | | * delimitation items are replaced. |
212 | | */ |
213 | | extern DCMTK_DCMDATA_EXPORT OFGlobal<OFBool> dcmReplaceWrongDelimitationItem; /* default OFFalse */ |
214 | | |
215 | | /** This flag enables the "silent" conversion of illegal OB/OW elements |
216 | | * with undefined length (other than PixelData) to SQ elements while reading. |
217 | | * The default behaviour is to reject such elements with an error message. |
218 | | */ |
219 | | extern DCMTK_DCMDATA_EXPORT OFGlobal<OFBool> dcmConvertUndefinedLengthOBOWtoSQ; /* default OFFalse */ |
220 | | |
221 | | /** This flag enables the "silent" conversion of incorrectly encoded |
222 | | * VOI LUT Sequence elements with VR=OW and explicit length into a sequence. |
223 | | * This incorrect encoding was detected "in the wild" in 2016. |
224 | | */ |
225 | | extern DCMTK_DCMDATA_EXPORT OFGlobal<OFBool> dcmConvertVOILUTSequenceOWtoSQ; /* default OFFalse */ |
226 | | |
227 | | /** This flag influences the behaviour when reading Pixel Data elements. |
228 | | * Pixel Data in those top level datasets that are using a compression-enabled |
229 | | * Transfer Syntax (with few exceptions such as Deflated TS), |
230 | | * is being stored in an encapsulated way. That means DICOM requires that the |
231 | | * Pixel Data then element uses an undefined length and internally uses a |
232 | | * pseudo sequence structure called Pixel Sequence with Pixel items inside. |
233 | | * If this flag is set to OFFalse (default), an error is reported when reading |
234 | | * datasets with encapsulated Transfer Syntaxes but with Pixel Data being |
235 | | * stored using explicit length encoding. |
236 | | * If this flag is set to OFTrue, such an invalid Pixel Data encoding is |
237 | | * accepted and the element is read with the given length as if it would be the |
238 | | * case for datasets in uncompressed transfer syntaxes. |
239 | | */ |
240 | | extern DCMTK_DCMDATA_EXPORT OFGlobal<OFBool> dcmUseExplLengthPixDataForEncTS; /* default OFFalse */ |
241 | | |
242 | | /** Abstract base class for most classes in module dcmdata. As a rule of thumb, |
243 | | * everything that is either a dataset or that can be identified with a DICOM |
244 | | * attribute tag is derived from class DcmObject. |
245 | | */ |
246 | | class DCMTK_DCMDATA_EXPORT DcmObject |
247 | | { |
248 | | public: |
249 | | |
250 | | /** constructor. |
251 | | * Create new object from given tag and length. |
252 | | * @param tag DICOM tag for the new element |
253 | | * @param len value length for the new element |
254 | | */ |
255 | | DcmObject(const DcmTag &tag, const Uint32 len = 0); |
256 | | |
257 | | /** copy constructor |
258 | | * @param obj item to be copied |
259 | | */ |
260 | | DcmObject(const DcmObject &obj); |
261 | | |
262 | | /// destructor |
263 | | virtual ~DcmObject(); |
264 | | |
265 | | /** clone method |
266 | | * @return deep copy of this object |
267 | | */ |
268 | | virtual DcmObject *clone() const = 0; |
269 | | |
270 | | /** copy assignment operator |
271 | | * @param obj object to be copied |
272 | | * @return reference to this object |
273 | | */ |
274 | | DcmObject &operator=(const DcmObject &obj); |
275 | | |
276 | | /** Virtual object copying. This method can be used for DcmObject |
277 | | * and derived classes to get a deep copy of an object. Internally |
278 | | * the assignment operator is called if the given DcmObject parameter |
279 | | * is of the same type as "this" object instance. If not, an error |
280 | | * is returned. This function permits copying an object by value |
281 | | * in a virtual way which therefore is different to just calling the |
282 | | * assignment operator of DcmElement which could result in slicing |
283 | | * the object. |
284 | | * @param rhs - [in] The instance to copy from. Has to be of the same |
285 | | * class type as "this" object |
286 | | * @return EC_Normal if copying was successful, error otherwise |
287 | | */ |
288 | | virtual OFCondition copyFrom(const DcmObject &rhs) = 0; |
289 | | |
290 | | /** return identifier for this class. Every class derived from this class |
291 | | * returns a unique value of type enum DcmEVR for this call. This is used |
292 | | * as a "poor man's RTTI" to correctly identify instances derived from |
293 | | * this class even on compilers not supporting RTTI. |
294 | | * @return type identifier of this class |
295 | | */ |
296 | | virtual DcmEVR ident() const = 0; |
297 | | |
298 | | /** return the value representation assigned to this object. |
299 | | * If object was read from a stream, this method returns the VR |
300 | | * that was defined in the stream for this object. It is, therefore, |
301 | | * possible that the VR does not match the one defined in the data |
302 | | * dictionary for the tag assigned to this object. |
303 | | * @return VR of this object |
304 | | */ |
305 | | inline DcmEVR getVR() const { return Tag.getEVR(); } |
306 | | |
307 | | /** check if this element is a string type, based on the VR. |
308 | | * Since the check is based on the VR and not on the class, |
309 | | * the result of this method is not a guarantee that the object |
310 | | * can be safely casted to one of the string-VR subclasses. |
311 | | * @return true if this object is a string VR, false otherwise |
312 | | */ |
313 | 0 | inline OFBool isaString() const { return Tag.getVR().isaString(); } |
314 | | |
315 | | /** check if this element is a leaf node in a dataset tree. |
316 | | * All subclasses of DcmElement except for DcmSequenceOfItems |
317 | | * are leaf nodes, while DcmSequenceOfItems, DcmItem, DcmDataset etc. |
318 | | * are not. |
319 | | * @return true if leaf node, false otherwise |
320 | | */ |
321 | | virtual OFBool isLeaf() const = 0; |
322 | | |
323 | | /** check if this element can be safely casted to DcmElement |
324 | | * @return true if DcmElement, false otherwise |
325 | | */ |
326 | | virtual OFBool isElement() const { return OFFalse; } |
327 | | |
328 | | /** check if this element is nested in a sequence of items, i.e.\ not a |
329 | | * top-level or stand-alone element |
330 | | * @return true if this element is nested, false otherwise |
331 | | */ |
332 | | virtual OFBool isNested() const; |
333 | | |
334 | | /** print object to a stream |
335 | | * @param out output stream |
336 | | * @param flags optional flag used to customize the output (see DCMTypes::PF_xxx) |
337 | | * @param level current level of nested items. Used for indentation. |
338 | | * @param pixelFileName not used (used in certain sub-classes of this class) |
339 | | * @param pixelCounter not used (used in certain sub-classes of this class) |
340 | | */ |
341 | | virtual void print(STD_NAMESPACE ostream &out, |
342 | | const size_t flags = 0, |
343 | | const int level = 0, |
344 | | const char *pixelFileName = NULL, |
345 | | size_t *pixelCounter = NULL) = 0; |
346 | | |
347 | | /** return the current transfer (read/write) state of this object. |
348 | | * @return transfer state of this object |
349 | | */ |
350 | | inline E_TransferState transferState() const { return fTransferState; } |
351 | | |
352 | | /** initialize the transfer state of this object. This method must be called |
353 | | * before this object is written to a stream or read (parsed) from a stream. |
354 | | */ |
355 | | virtual void transferInit(void); |
356 | | |
357 | | /** finalize the transfer state of this object. This method must be called |
358 | | * when reading/writing this object from/to a stream has been completed. |
359 | | */ |
360 | | virtual void transferEnd(void); |
361 | | |
362 | | /** get root dataset/item (top-level) that contains this object. Internally, |
363 | | * the list of parent pointers is followed in order to find the root. If |
364 | | * this object has no parent item, a pointer to this object is returned |
365 | | * instead. |
366 | | * @return pointer to the root dataset/item (might be NULL) |
367 | | */ |
368 | | DcmItem *getRootItem(); |
369 | | |
370 | | /** get parent item of this object. In case of a top-level element, this is |
371 | | * either the main dataset or the file meta-information. In case of a nested |
372 | | * element, this is the surrounding item. |
373 | | * @return pointer to the parent item of this object (might be NULL) |
374 | | */ |
375 | | virtual DcmItem *getParentItem(); |
376 | | |
377 | | /** get parent of this object. If this object is an element that has been |
378 | | * inserted into a dataset/item, the parent is this particular dataset/item. |
379 | | * If this object is an item that has been inserted into a sequence, the |
380 | | * parent is this particular sequence. If this object has not been inserted |
381 | | * into a dataset/item or sequence, NULL is returned. |
382 | | * @return pointer to the parent of this object (might be NULL) |
383 | | */ |
384 | | inline DcmObject *getParent() { return Parent; } |
385 | | |
386 | | /** get parent of this object. If this object is an element that has been |
387 | | * inserted into a dataset/item, the parent is this particular dataset/item. |
388 | | * If this object is an item that has been inserted into a sequence, the |
389 | | * parent is this particular sequence. If this object has not been inserted |
390 | | * into a dataset/item or sequence, NULL is returned. |
391 | | * @return pointer to the parent of this object (might be NULL) |
392 | | */ |
393 | | inline const DcmObject *getParent() const { return Parent; } |
394 | | |
395 | | /** set parent of this object. NULL means no parent. |
396 | | * NB: This method is used by derived classes for internal purposes only. |
397 | | * @param parent pointer to the parent of this object |
398 | | */ |
399 | | inline void setParent(DcmObject *parent) { Parent = parent; } |
400 | | |
401 | | /** return the group number of the attribute tag for this object |
402 | | * @return group number of the attribute tag for this object |
403 | | */ |
404 | | inline Uint16 getGTag() const { return Tag.getGTag(); } |
405 | | |
406 | | /** return the element number of the attribute tag for this object |
407 | | * @return element number of the attribute tag for this object |
408 | | */ |
409 | | inline Uint16 getETag() const { return Tag.getETag(); } |
410 | | |
411 | | /** return const reference to the attribute tag for this object |
412 | | * @return const reference to the attribute tag for this object |
413 | | */ |
414 | 1.26M | inline const DcmTag &getTag() const { return Tag; } |
415 | | |
416 | | /** assign group tag (but not element tag) of the attribute tag for this object. |
417 | | * This is sometimes useful when creating repeating group elements. |
418 | | * @param gtag new attribute group tag |
419 | | */ |
420 | 0 | inline void setGTag(Uint16 gtag) { Tag.setGroup(gtag); } |
421 | | |
422 | | /** assign a new Value Representation (VR) to this object. This operation |
423 | | * is only supported for very few subclasses derived from this class, |
424 | | * in particular for classes handling pixel data which may either be |
425 | | * of OB or OW value representation. |
426 | | * @param vr value representation |
427 | | * @return EC_Normal if successful, an error code otherwise |
428 | | */ |
429 | | #ifdef DOXYGEN |
430 | | virtual OFCondition setVR(DcmEVR vr) |
431 | | #else |
432 | | virtual OFCondition setVR(DcmEVR /* vr */) |
433 | | #endif |
434 | | { |
435 | | return EC_IllegalCall; |
436 | | } |
437 | | |
438 | | /** get value multiplicity of this object. |
439 | | * Please note that depending on the Value Representation (VR), subclasses |
440 | | * derived from this class either return the number of currently stored |
441 | | * values or the constant value 1 (as defined in the DICOM standard). |
442 | | * See getNumberOfValues(), which always returns the number of stored values. |
443 | | * @return value multiplicity of this object |
444 | | */ |
445 | | virtual unsigned long getVM() = 0; |
446 | | |
447 | | /** get number of values stored in this object |
448 | | * @return number of values in this object |
449 | | */ |
450 | | virtual unsigned long getNumberOfValues() = 0; |
451 | | |
452 | | /** calculate the length of this DICOM element when encoded with the |
453 | | * given transfer syntax and the given encoding type for sequences. |
454 | | * For elements, the length includes the length of the tag, length field, |
455 | | * VR field and the value itself, for items and sequences it returns |
456 | | * the length of the complete item or sequence including delimitation tags |
457 | | * if applicable. |
458 | | * @warning Since calcElementLength() returns a 32 bit integer, an |
459 | | * overflow during calculation is possible for some derived classes that |
460 | | * actually represent a compound value (e.g. items like DcmPixelItem). |
461 | | * Such overflows will be detected, in which case the maximum possible |
462 | | * value will be returned instead, coinciding with DCM_UndefinedLength. |
463 | | * @warning The implementation in DcmPixelData may return zero if no |
464 | | * conforming representation exists and set the |
465 | | * EC_RepresentationNotFound error flag to indicated it. |
466 | | * @warning When calculation the length of a sequence or an item |
467 | | * containing multiple attributes, the implementation may return |
468 | | * DCM_UndefinedLength to indicate a value that can not be encoded as |
469 | | * a 32 bit length field. It will even do so if |
470 | | * "dcmWriteOversizedSeqsAndItemsUndefined" is disabled, but then also |
471 | | * set the EC_SeqOrItemContentOverflow error flag (inside getLength()) |
472 | | * to indicated it. |
473 | | * @note Just check for zero or DCM_UndefinedLength return value and then |
474 | | * have a look at the error flag in either case. |
475 | | * @param xfer transfer syntax for length calculation |
476 | | * @param enctype sequence encoding type for length calculation |
477 | | * @return length of DICOM element |
478 | | */ |
479 | | virtual Uint32 calcElementLength(const E_TransferSyntax xfer, |
480 | | const E_EncodingType enctype) = 0; |
481 | | |
482 | | /** calculate the value length (without attribute tag, VR and length field) |
483 | | * of this DICOM element when encoded with the given transfer syntax and |
484 | | * the given encoding type for sequences. Never returns undefined length. |
485 | | * @param xfer transfer syntax for length calculation |
486 | | * @param enctype sequence encoding type for length calculation |
487 | | * @return value length of DICOM element |
488 | | */ |
489 | | virtual Uint32 getLength(const E_TransferSyntax xfer = EXS_LittleEndianImplicit, |
490 | | const E_EncodingType enctype = EET_UndefinedLength) = 0; |
491 | | |
492 | | /** check if this DICOM object can be encoded in the given transfer syntax. |
493 | | * @param newXfer transfer syntax in which the DICOM object is to be encoded |
494 | | * @param oldXfer transfer syntax in which the DICOM object was read or created. |
495 | | * @return true if object can be encoded in desired transfer syntax, false otherwise. |
496 | | */ |
497 | | virtual OFBool canWriteXfer(const E_TransferSyntax newXfer, |
498 | | const E_TransferSyntax oldXfer) = 0; |
499 | | |
500 | | /** read object from a stream. |
501 | | * @param inStream DICOM input stream |
502 | | * @param ixfer transfer syntax to use when parsing |
503 | | * @param glenc handling of group length parameters |
504 | | * @param maxReadLength attribute values larger than this value are skipped |
505 | | * while parsing and read later upon first access if the stream type supports |
506 | | * this. |
507 | | * @return EC_Normal if successful, an error code otherwise |
508 | | */ |
509 | | virtual OFCondition read(DcmInputStream &inStream, |
510 | | const E_TransferSyntax ixfer, |
511 | | const E_GrpLenEncoding glenc = EGL_noChange, |
512 | | const Uint32 maxReadLength = DCM_MaxReadLength) = 0; |
513 | | |
514 | | /** write object to a stream (abstract) |
515 | | * @param outStream DICOM output stream |
516 | | * @param oxfer output transfer syntax |
517 | | * @param enctype encoding types (undefined or explicit length) |
518 | | * @param wcache pointer to write cache object, may be NULL |
519 | | * @return status, EC_Normal if successful, an error code otherwise |
520 | | */ |
521 | | virtual OFCondition write(DcmOutputStream &outStream, |
522 | | const E_TransferSyntax oxfer, |
523 | | const E_EncodingType enctype, |
524 | | DcmWriteCache *wcache) = 0; |
525 | | |
526 | | /** write object in XML format to a stream |
527 | | * @param out output stream to which the XML document is written |
528 | | * @param flags optional flag used to customize the output (see DCMTypes::XF_xxx) |
529 | | * @return status, always returns EC_Illegal Call |
530 | | */ |
531 | | virtual OFCondition writeXML(STD_NAMESPACE ostream &out, |
532 | | const size_t flags = 0); |
533 | | |
534 | | /** write object in JSON format to a stream |
535 | | * @param out output stream to which the JSON document is written |
536 | | * @param format used to format and customize the output |
537 | | * @return status, always returns EC_Illegal Call |
538 | | */ |
539 | | virtual OFCondition writeJson(STD_NAMESPACE ostream &out, |
540 | | DcmJsonFormat &format); |
541 | | |
542 | | /** special write method for creation of digital signatures (abstract) |
543 | | * @param outStream DICOM output stream |
544 | | * @param oxfer output transfer syntax |
545 | | * @param enctype encoding types (undefined or explicit length) |
546 | | * @param wcache pointer to write cache object, may be NULL |
547 | | * @return status, EC_Normal if successful, an error code otherwise |
548 | | */ |
549 | | virtual OFCondition writeSignatureFormat(DcmOutputStream &outStream, |
550 | | const E_TransferSyntax oxfer, |
551 | | const E_EncodingType enctype, |
552 | | DcmWriteCache *wcache) = 0; |
553 | | |
554 | | /** returns true if the current object may be included in a digital signature |
555 | | * @return true if signable, false otherwise |
556 | | */ |
557 | | virtual OFBool isSignable() const; |
558 | | |
559 | | /** returns true if the object contains an element with Unknown VR at any nesting level |
560 | | * @return true if the object contains an element with Unknown VR, false otherwise |
561 | | */ |
562 | | virtual OFBool containsUnknownVR() const; |
563 | | |
564 | | /** check if this object contains non-ASCII characters |
565 | | * @param checkAllStrings not used in this class |
566 | | * @return always returns false, i.e. no extended characters used |
567 | | */ |
568 | | virtual OFBool containsExtendedCharacters(const OFBool checkAllStrings = OFFalse); |
569 | | |
570 | | /** check if this object is affected by SpecificCharacterSet |
571 | | * @return always returns false, i.e. not affected by SpecificCharacterSet |
572 | | */ |
573 | | virtual OFBool isAffectedBySpecificCharacterSet() const; |
574 | | |
575 | | /** convert this object from the currently selected source character set to the |
576 | | * currently selected destination character set (if affected by SpecificCharacterSet) |
577 | | * @param converter character set converter to be used to convert the element values |
578 | | * @return always returns EC_Normal, since there is nothing to do in this base class |
579 | | */ |
580 | | virtual OFCondition convertCharacterSet(DcmSpecificCharacterSet &converter); |
581 | | |
582 | | /** check if this object is empty |
583 | | * @param normalize normalize value before checking (ignore non-significant characters) |
584 | | * @return true if object is empty, i.e. has no value, false otherwise |
585 | | */ |
586 | | virtual OFBool isEmpty(const OFBool normalize = OFTrue); |
587 | | |
588 | | /** clear (remove) attribute value |
589 | | * @return EC_Normal if successful, an error code otherwise |
590 | | */ |
591 | | virtual OFCondition clear() = 0; |
592 | | |
593 | | /** check the currently stored element value |
594 | | * @param autocorrect correct value length if OFTrue |
595 | | * @return status, EC_Normal if value length is correct, an error code otherwise |
596 | | */ |
597 | | virtual OFCondition verify(const OFBool autocorrect = OFFalse) = 0; |
598 | | |
599 | | /** this method is only used in container classes derived from this class, |
600 | | * that is, DcmItem and DcmSequenceOfItems. It returns a pointer to the |
601 | | * next object in the list AFTER the given object. If the caller passes NULL, |
602 | | * a pointer to the first object in the list is returned. If the given object |
603 | | * is not found, the given object is the last one in the list or the list is empty, |
604 | | * NULL is returned. |
605 | | * @param obj pointer to one object in the container; we are looking for the |
606 | | * next entry after this one. NULL if looking for the first entry. |
607 | | * @return pointer to next object in container or NULL if not found |
608 | | */ |
609 | | virtual DcmObject *nextInContainer(const DcmObject *obj); |
610 | | |
611 | | /** this method enables a stack based, depth-first traversal of a complete |
612 | | * hierarchical DICOM dataset (that is, classes derived from DcmItem or |
613 | | * DcmSequenceOfItems). With each call of this method, the next object |
614 | | * in the tree is located and marked on the stack. |
615 | | * @param stack "cursor" for current position in the dataset. The stack |
616 | | * will contain a pointer to each dataset, sequence, item and element |
617 | | * from the main dataset down to the current element, and is updated |
618 | | * upon each call to this method. An empty stack is equivalent to a stack |
619 | | * containing a pointer to this object only. |
620 | | * @param intoSub if true, the nextObject method will perform a hierarchical |
621 | | * search through the dataset (depth-first), if false, only the current |
622 | | * container object will be traversed (e.g., all elements of an item |
623 | | * or all items of a sequence). |
624 | | * @return EC_Normal if value length is correct, an error code otherwise |
625 | | */ |
626 | | virtual OFCondition nextObject(DcmStack &stack, |
627 | | const OFBool intoSub); |
628 | | |
629 | | /** a complex, stack-based, hierarchical search method. It allows for a search |
630 | | * for a DICOM object with a given attribute within a given container, |
631 | | * hierarchically, from a starting position identified through a cursor stack. |
632 | | * @param xtag the DICOM attribute tag we are searching for |
633 | | * @param resultStack Depending on the search mode (see below), this parameter |
634 | | * either serves as an input and output parameter, or as an output parameter |
635 | | * only (the latter being the default). When used as an input parameter, |
636 | | * the cursor stack defines the start position for the search within a |
637 | | * hierarchical DICOM dataset. Upon successful return, the stack contains |
638 | | * the position of the element found, in the form of a pointer to each dataset, |
639 | | * sequence, item and element from the main dataset down to the found element. |
640 | | * @param mode search mode, controls how the search stack is handled. |
641 | | * In the default mode, ESM_fromHere, the stack is ignored on input, and |
642 | | * the search starts in the object for which this method is called. |
643 | | * In the other modes, the stack is used both as an input and an output |
644 | | * parameter and defines the starting point for the search. |
645 | | * @param searchIntoSub if true, the search will be performed hierarchically descending |
646 | | * into the sequences and items of the dataset. If false, only the current container |
647 | | * (sequence or item) will be traversed. |
648 | | * @return EC_Normal if found, EC_TagNotFound if not found, an error code is something went wrong. |
649 | | */ |
650 | | virtual OFCondition search(const DcmTagKey &xtag, |
651 | | DcmStack &resultStack, |
652 | | E_SearchMode mode = ESM_fromHere, |
653 | | OFBool searchIntoSub = OFTrue); |
654 | | |
655 | | /** this method loads all attribute values maintained by this object and |
656 | | * all sub-objects (in case of a container such as DcmDataset) into memory. |
657 | | * After a call to this method, the file from which a dataset was read may safely |
658 | | * be deleted or replaced. For large files, this method may obviously allocate large |
659 | | * amounts of memory. |
660 | | * @return EC_Normal if successful, an error code otherwise |
661 | | */ |
662 | | virtual OFCondition loadAllDataIntoMemory() = 0; |
663 | | |
664 | | /** return the current value of the Length field (which is different from the functionality |
665 | | * of the public getLength() method). Only needed for internal purposes and for checker tools |
666 | | * that verify values against the length field. |
667 | | * @return current value of length field |
668 | | */ |
669 | | Uint32 getLengthField() const { return Length; } |
670 | | |
671 | | protected: |
672 | | |
673 | | /** print line indentation, e.g.\ a couple of spaces for each nesting level. |
674 | | * Depending on the value of 'flags' other visualizations are also possible. |
675 | | * @param out output stream |
676 | | * @param flags used to customize the output (see DCMTypes::PF_xxx) |
677 | | * @param level current level of nested items. Used for indentation. |
678 | | */ |
679 | | void printNestingLevel(STD_NAMESPACE ostream &out, |
680 | | const size_t flags, |
681 | | const int level); |
682 | | |
683 | | /** print beginning of the info line. |
684 | | * The default output is tag and value representation, though other |
685 | | * visualizations are possible depending on the value of 'flags'. |
686 | | * @param out output stream |
687 | | * @param flags used to customize the output (see DCMTypes::PF_xxx) |
688 | | * @param level current level of nested items. Used for indentation. |
689 | | * @param tag optional tag used to print the data element information |
690 | | */ |
691 | | void printInfoLineStart(STD_NAMESPACE ostream &out, |
692 | | const size_t flags, |
693 | | const int level, |
694 | | DcmTag *tag = NULL); |
695 | | |
696 | | /** print end of the info line. |
697 | | * The default output is length, value multiplicity and tag name, though |
698 | | * other visualizations are possible depending on the value of 'flags'. |
699 | | * @param out output stream |
700 | | * @param flags used to customize the output (see DCMTypes::PF_xxx) |
701 | | * @param printedLength number of characters printed after line start. |
702 | | * Used for padding purposes. |
703 | | * @param tag optional tag used to print the data element information |
704 | | */ |
705 | | void printInfoLineEnd(STD_NAMESPACE ostream &out, |
706 | | const size_t flags, |
707 | | const unsigned long printedLength = 0xffffffff /*no padding*/, |
708 | | DcmTag *tag = NULL); |
709 | | |
710 | | /** print given text with element information. |
711 | | * Calls printInfoLineStart() and printInfoLineEnd() to frame the 'info' text. |
712 | | * @param out output stream |
713 | | * @param flags used to customize the output (see DCMTypes::PF_xxx) |
714 | | * @param level current level of nested items. Used for indentation. |
715 | | * @param info text to be printed |
716 | | * @param tag optional tag used to print the data element information |
717 | | * @param isInfo optional flag indicating whether this text is really given for |
718 | | * informational purposes only. Used to choose the correct output color. |
719 | | */ |
720 | | virtual void printInfoLine(STD_NAMESPACE ostream &out, |
721 | | const size_t flags, |
722 | | const int level = 0, |
723 | | const char *info = NULL, |
724 | | DcmTag *tag = NULL, |
725 | | const OFBool isInfo = OFTrue); |
726 | | |
727 | | /** static helper function that writes a given attribute tag to a binary |
728 | | * output stream using the byte order indicated by the transfer syntax. |
729 | | * @param outStream output stream |
730 | | * @param tag tag to write to the stream |
731 | | * @param oxfer transfer syntax defining the byte order |
732 | | * @return EC_Normal if successful, an error code otherwise |
733 | | */ |
734 | | static OFCondition writeTag(DcmOutputStream &outStream, |
735 | | const DcmTag &tag, |
736 | | const E_TransferSyntax oxfer); |
737 | | |
738 | | /** write tag, VR and length field to the given output stream |
739 | | * @param outStream output stream |
740 | | * @param oxfer transfer syntax for writing |
741 | | * @param writtenBytes number of bytes written to stream returned in this parameter |
742 | | * @return EC_Normal if successful, an error code otherwise |
743 | | */ |
744 | | virtual OFCondition writeTagAndLength(DcmOutputStream &outStream, |
745 | | const E_TransferSyntax oxfer, // in |
746 | | Uint32 &writtenBytes) const; // out |
747 | | |
748 | | /** return the number of bytes needed to serialize the |
749 | | * tag, VR and length information of the current object using the given |
750 | | * transfer syntax. |
751 | | * @param oxfer The transfer syntax used for encoding |
752 | | * @return number of bytes, may be 8 or 12 depending on VR and transfer syntax. |
753 | | */ |
754 | | virtual Uint32 getTagAndLengthSize(const E_TransferSyntax oxfer) const; |
755 | | |
756 | | /** return the DICOM attribute tag name for this object. If not known yet, will |
757 | | * be looked up in the dictionary and cached. Therefore, method is not const. |
758 | | * @return tag name for this attribute |
759 | | */ |
760 | | const char *getTagName() { return Tag.getTagName(); } |
761 | | |
762 | | /** set the VR for this attribute |
763 | | * @param vr new VR for this attribute. |
764 | | */ |
765 | | void setTagVR(DcmEVR vr) { Tag.setVR(vr); } |
766 | | |
767 | | /** return the current transfer state of this object during serialization/deserialization |
768 | | * @return current transfer state of this object |
769 | | */ |
770 | | E_TransferState getTransferState() const { return fTransferState; } |
771 | | |
772 | | /** set the current transfer state of this object during serialization/deserialization |
773 | | * @param newState new transfer state of this object |
774 | | */ |
775 | | void setTransferState(E_TransferState newState) { fTransferState = newState; } |
776 | | |
777 | | /** return the number of transferred bytes for this object during serialization/deserialization |
778 | | * @return number of transferred bytes |
779 | | */ |
780 | | Uint32 getTransferredBytes() const { return fTransferredBytes; } |
781 | | |
782 | | /** set the number of transferred bytes for this object during serialization/deserialization |
783 | | * @param val number of transferred bytes |
784 | | */ |
785 | | void setTransferredBytes(Uint32 val) { fTransferredBytes = val; } |
786 | | |
787 | | /** add to the number of transferred bytes for this object during serialization/deserialization |
788 | | * @param val number of additional transferred bytes to add to existing value |
789 | | */ |
790 | | void incTransferredBytes(Uint32 val) { fTransferredBytes += val; } |
791 | | |
792 | | /** set the current value of the Length field |
793 | | * @param val new value of the Length field |
794 | | */ |
795 | | void setLengthField(Uint32 val) { Length = val; } |
796 | | |
797 | | public: |
798 | | |
799 | | /** helper class to print a DcmObject to an ostream using operator<< |
800 | | */ |
801 | | class DCMTK_DCMDATA_EXPORT PrintHelper |
802 | | { |
803 | | private: |
804 | | /** Undefined assignment operator. This is needed to work around a |
805 | | * compiler warning on VC2008 with the highest warning level. |
806 | | */ |
807 | | PrintHelper& operator=(PrintHelper &); |
808 | | |
809 | | public: |
810 | | /** construct a PrintHelper |
811 | | * @param dcmobj DcmObject you want to print |
812 | | * @param flags flags to use for DcmObject::print() |
813 | | * @param level level to use for DcmObject::print() |
814 | | */ |
815 | | explicit PrintHelper(DcmObject &dcmobj, size_t flags = 0, int level = 0) |
816 | | : dcmobj_(dcmobj), flags_(flags), level_(level) |
817 | 0 | {} |
818 | | |
819 | | DcmObject &dcmobj_; |
820 | | const size_t flags_; |
821 | | const int level_; |
822 | | }; |
823 | | |
824 | | /* member variables */ |
825 | | |
826 | | protected: |
827 | | |
828 | | /// error flag for this object. |
829 | | OFCondition errorFlag; |
830 | | |
831 | | private: |
832 | | |
833 | | /// the DICOM attribute tag and VR for this object |
834 | | DcmTag Tag; |
835 | | |
836 | | /// the length of this attribute as read from stream, may be undefined length |
837 | | Uint32 Length; |
838 | | |
839 | | /// transfer state during read and write operations |
840 | | E_TransferState fTransferState; |
841 | | |
842 | | /// number of bytes already read/written during transfer |
843 | | Uint32 fTransferredBytes; |
844 | | |
845 | | /// pointer to parent object if contained in a dataset/item (might be NULL) |
846 | | DcmObject *Parent; |
847 | | }; // class DcmObject |
848 | | |
849 | | /** Print a DcmObject::PrintHelper to an ostream. |
850 | | * @param stream stream to print to |
851 | | * @param obj object which will be print()ed |
852 | | * @return the stream argument |
853 | | */ |
854 | | static inline STD_NAMESPACE ostream& operator<<(STD_NAMESPACE ostream &stream, DcmObject::PrintHelper obj) |
855 | 0 | { |
856 | 0 | obj.dcmobj_.print(stream, obj.flags_, obj.level_); |
857 | 0 | return stream; |
858 | 0 | } Unexecuted instantiation: dcmtk_dicom_fuzzer.cc:operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, DcmObject::PrintHelper) Unexecuted instantiation: dcmtk_meta_fuzzer.cc:operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, DcmObject::PrintHelper) Unexecuted instantiation: dcmtk_image_fuzzer.cc:operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, DcmObject::PrintHelper) |
859 | | |
860 | | #endif // DCOBJECT_H |