00001 /* 00002 * 00003 * Copyright (C) 1994-2010, OFFIS e.V. 00004 * All rights reserved. See COPYRIGHT file for details. 00005 * 00006 * This software and supporting documentation were developed by 00007 * 00008 * OFFIS e.V. 00009 * R&D Division Health 00010 * Escherweg 2 00011 * D-26121 Oldenburg, Germany 00012 * 00013 * 00014 * Module: dcmdata 00015 * 00016 * Author: Gerd Ehlers 00017 * 00018 * Purpose: 00019 * This file contains the interface to routines which provide 00020 * DICOM object encoding/decoding, search and lookup facilities. 00021 * 00022 * Last Update: $Author: joergr $ 00023 * Update Date: $Date: 2010-10-29 10:57:17 $ 00024 * CVS/RCS Revision: $Revision: 1.70 $ 00025 * Status: $State: Exp $ 00026 * 00027 * CVS/RCS Log at end of file 00028 * 00029 */ 00030 00031 00032 #ifndef DCOBJECT_H 00033 #define DCOBJECT_H 00034 00035 #include "dcmtk/config/osconfig.h" /* make sure OS specific configuration is included first */ 00036 00037 #include "dcmtk/ofstd/ofglobal.h" 00038 #include "dcmtk/dcmdata/dcerror.h" 00039 #include "dcmtk/dcmdata/dcxfer.h" 00040 #include "dcmtk/dcmdata/dctag.h" 00041 #include "dcmtk/dcmdata/dcstack.h" 00042 00043 00044 // forward declarations 00045 class DcmOutputStream; 00046 class DcmInputStream; 00047 class DcmWriteCache; 00048 00049 // Undefined Length Identifier now defined in dctypes.h 00050 00051 // Maxinum number of read bytes for a Value Element 00052 const Uint32 DCM_MaxReadLength = 4096; 00053 00054 // Maximum length of tag and length in a DICOM element 00055 const Uint32 DCM_TagInfoLength = 12; 00056 00057 // Optimum line length if not all data printed 00058 const Uint32 DCM_OptPrintLineLength = 70; 00059 00060 // Optimum value length if not all data printed 00061 const Uint32 DCM_OptPrintValueLength = 40; 00062 00063 // Optimum attribute name length (for tree output) 00064 const Uint32 DCM_OptPrintAttributeNameLength = 35; 00065 00070 extern OFGlobal<OFBool> dcmEnableAutomaticInputDataCorrection; /* default OFTrue */ 00071 00081 extern OFGlobal<OFBool> dcmAcceptOddAttributeLength; /* default OFTrue */ 00082 00095 extern OFGlobal<OFBool> dcmEnableCP246Support; /* default OFTrue */ 00096 00105 extern OFGlobal<OFBool> dcmEnableOldSignatureFormat; /* default OFFalse */ 00106 00112 extern OFGlobal<OFBool> dcmAutoDetectDatasetXfer; /* default OFFalse */ 00113 00119 extern OFGlobal<OFBool> dcmAcceptUnexpectedImplicitEncoding; /* default OFFalse */ 00120 00130 extern OFGlobal<OFBool> dcmReadImplPrivAttribMaxLengthAsSQ; /* default OFFalse */ 00131 00138 extern OFGlobal<OFBool> dcmIgnoreParsingErrors; /* default OFFalse */ 00139 00153 extern OFGlobal<DcmTagKey> dcmStopParsingAfterElement; /* default OFTrue */ 00154 00165 extern OFGlobal<OFBool> dcmWriteOversizedSeqsAndItemsUndefined; /* default OFTrue */ 00166 00172 extern OFGlobal<OFBool> dcmIgnoreFileMetaInformationGroupLength; /* default OFFalse */ 00173 00174 00179 class DcmObject 00180 { 00181 public: 00182 00188 DcmObject(const DcmTag &tag, const Uint32 len = 0); 00189 00193 DcmObject(const DcmObject &obj); 00194 00196 virtual ~DcmObject(); 00197 00201 virtual DcmObject *clone() const = 0; 00202 00207 DcmObject &operator=(const DcmObject &obj); 00208 00221 virtual OFCondition copyFrom(const DcmObject &rhs) = 0; 00222 00229 virtual DcmEVR ident() const = 0; 00230 00238 inline DcmEVR getVR() const { return Tag.getEVR(); } 00239 00246 inline OFBool isaString() const { return Tag.getVR().isaString(); } 00247 00254 virtual OFBool isLeaf() const = 0; 00255 00263 virtual void print(STD_NAMESPACE ostream &out, 00264 const size_t flags = 0, 00265 const int level = 0, 00266 const char *pixelFileName = NULL, 00267 size_t *pixelCounter = NULL) = 0; 00268 00272 inline E_TransferState transferState() const { return fTransferState; } 00273 00277 virtual void transferInit(void); 00278 00282 virtual void transferEnd(void); 00283 00287 inline Uint16 getGTag() const { return Tag.getGTag(); } 00288 00292 inline Uint16 getETag() const { return Tag.getETag(); } 00293 00297 inline const DcmTag &getTag() const { return Tag; } 00298 00303 inline void setGTag(Uint16 gtag) { Tag.setGroup(gtag); } 00304 00312 virtual OFCondition setVR(DcmEVR /*vr*/) { return EC_IllegalCall; } 00313 00317 virtual unsigned long getVM() = 0; 00318 00329 virtual Uint32 calcElementLength(const E_TransferSyntax xfer, 00330 const E_EncodingType enctype) = 0; 00331 00339 virtual Uint32 getLength(const E_TransferSyntax xfer = EXS_LittleEndianImplicit, 00340 const E_EncodingType enctype = EET_UndefinedLength) = 0; 00341 00347 virtual OFBool canWriteXfer(const E_TransferSyntax newXfer, 00348 const E_TransferSyntax oldXfer) = 0; 00349 00359 virtual OFCondition read(DcmInputStream &inStream, 00360 const E_TransferSyntax ixfer, 00361 const E_GrpLenEncoding glenc = EGL_noChange, 00362 const Uint32 maxReadLength = DCM_MaxReadLength) = 0; 00363 00371 virtual OFCondition write(DcmOutputStream &outStream, 00372 const E_TransferSyntax oxfer, 00373 const E_EncodingType enctype, 00374 DcmWriteCache *wcache) = 0; 00375 00381 virtual OFCondition writeXML(STD_NAMESPACE ostream&out, 00382 const size_t flags = 0); 00383 00391 virtual OFCondition writeSignatureFormat(DcmOutputStream &outStream, 00392 const E_TransferSyntax oxfer, 00393 const E_EncodingType enctype, 00394 DcmWriteCache *wcache) = 0; 00395 00399 virtual OFBool isSignable() const; 00400 00404 virtual OFBool containsUnknownVR() const; 00405 00410 virtual OFBool containsExtendedCharacters(const OFBool checkAllStrings = OFFalse); 00411 00415 virtual OFBool isAffectedBySpecificCharacterSet() const; 00416 00421 virtual OFBool isEmpty(const OFBool normalize = OFTrue); 00422 00426 virtual OFCondition clear() = 0; 00427 00432 virtual OFCondition verify(const OFBool autocorrect = OFFalse) = 0; 00433 00444 virtual DcmObject *nextInContainer(const DcmObject *obj); 00445 00461 virtual OFCondition nextObject(DcmStack &stack, 00462 const OFBool intoSub); 00463 00485 virtual OFCondition search(const DcmTagKey &xtag, 00486 DcmStack &resultStack, 00487 E_SearchMode mode = ESM_fromHere, 00488 OFBool searchIntoSub = OFTrue); 00489 00497 virtual OFCondition loadAllDataIntoMemory() = 0; 00498 00504 Uint32 getLengthField() const { return Length; } 00505 00506 protected: 00507 00514 void printNestingLevel(STD_NAMESPACE ostream &out, 00515 const size_t flags, 00516 const int level); 00517 00526 void printInfoLineStart(STD_NAMESPACE ostream &out, 00527 const size_t flags, 00528 const int level, 00529 DcmTag *tag = NULL); 00530 00540 void printInfoLineEnd(STD_NAMESPACE ostream &out, 00541 const size_t flags, 00542 const unsigned long printedLength = 0xffffffff /*no padding*/, 00543 DcmTag *tag = NULL); 00544 00556 virtual void printInfoLine(STD_NAMESPACE ostream &out, 00557 const size_t flags, 00558 const int level = 0, 00559 const char *info = NULL, 00560 DcmTag *tag = NULL, 00561 const OFBool isInfo = OFTrue); 00562 00570 static OFCondition writeTag(DcmOutputStream &outStream, 00571 const DcmTag &tag, 00572 const E_TransferSyntax oxfer); 00573 00580 virtual OFCondition writeTagAndLength(DcmOutputStream &outStream, 00581 const E_TransferSyntax oxfer, // in 00582 Uint32 &writtenBytes) const; // out 00583 00590 virtual Uint32 getTagAndLengthSize(const E_TransferSyntax oxfer) const; 00591 00596 const char *getTagName() { return Tag.getTagName(); } 00597 00601 void setTagVR(DcmEVR vr) { Tag.setVR(vr); } 00602 00606 E_TransferState getTransferState() const { return fTransferState; } 00607 00611 void setTransferState(E_TransferState newState) { fTransferState = newState; } 00612 00616 Uint32 getTransferredBytes() const { return fTransferredBytes; } 00617 00621 void setTransferredBytes(Uint32 val) { fTransferredBytes = val; } 00622 00626 void incTransferredBytes(Uint32 val) { fTransferredBytes += val; } 00627 00631 void setLengthField(Uint32 val) { Length = val; } 00632 00633 public: 00636 class PrintHelper 00637 { 00638 private: 00642 PrintHelper& operator=(PrintHelper &); 00643 00644 public: 00650 explicit PrintHelper(DcmObject &dcmobj, size_t flags = 0, int level = 0) 00651 : dcmobj_(dcmobj), flags_(flags), level_(level) 00652 {} 00653 00654 DcmObject &dcmobj_; 00655 const size_t flags_; 00656 const int level_; 00657 }; 00658 00659 /* member variables */ 00660 00661 protected: 00662 00664 OFCondition errorFlag; 00665 00666 private: 00667 00669 DcmTag Tag; 00670 00672 Uint32 Length; 00673 00675 E_TransferState fTransferState; 00676 00678 Uint32 fTransferredBytes; 00679 00680 }; // class DcmObject 00681 00687 static inline STD_NAMESPACE ostream& operator<<(STD_NAMESPACE ostream &stream, DcmObject::PrintHelper obj) 00688 { 00689 obj.dcmobj_.print(stream, obj.flags_, obj.level_); 00690 return stream; 00691 } 00692 00693 #endif // DCOBJECT_H 00694 00695 00696 /* 00697 * CVS/RCS Log: 00698 * $Log: dcobject.h,v $ 00699 * Revision 1.70 2010-10-29 10:57:17 joergr 00700 * Added support for colored output to the print() method. 00701 * 00702 * Revision 1.69 2010-10-14 13:15:41 joergr 00703 * Updated copyright header. Added reference to COPYRIGHT file. 00704 * 00705 * Revision 1.68 2010-06-18 08:17:57 uli 00706 * Added undefined assignment operator to PrintHelper to work around 00707 * a warning with VC2008. 00708 * 00709 * Revision 1.67 2010-03-01 09:08:44 uli 00710 * Removed some unnecessary include directives in the headers. 00711 * 00712 * Revision 1.66 2010-02-22 11:39:54 uli 00713 * Remove some unneeded includes. 00714 * 00715 * Revision 1.65 2009-11-04 09:58:07 uli 00716 * Switched to logging mechanism provided by the "new" oflog module 00717 * 00718 * Revision 1.64 2009-10-13 14:26:09 uli 00719 * Added the DcmObject::PrintHelper helper class. This class can be used to 00720 * print DcmObject instances with oflog's logging macros. 00721 * 00722 * Revision 1.63 2009-08-07 14:40:38 joergr 00723 * Enhanced isEmpty() method by checking whether the data element value consists 00724 * of non-significant characters only. 00725 * 00726 * Revision 1.62 2009-06-04 16:52:14 joergr 00727 * Added new parsing flag that allows for ignoring the value of File Meta 00728 * Information Group Length (0002,0000). 00729 * 00730 * Revision 1.61 2009-03-25 10:22:09 joergr 00731 * Added new method isEmpty() to DICOM object, item and sequence class. 00732 * 00733 * Revision 1.60 2009-03-05 14:07:56 onken 00734 * Fixed typo. 00735 * 00736 * Revision 1.59 2009-03-05 13:35:47 onken 00737 * Added checks for sequence and item lengths which prevents overflow in length 00738 * field, if total length of contained items (or sequences) exceeds 00739 * 32-bit length field. Also introduced new flag (default: enabled) 00740 * for writing in explicit length mode, which allows for automatically 00741 * switching encoding of only that very sequence/item to undefined 00742 * length coding (thus permitting to actually write the file). 00743 * 00744 * Revision 1.58 2009-02-11 13:16:32 onken 00745 * Added global parser flag permitting to stop parsing after a specific 00746 * element was parsed on dataset level (useful for removing garbage at 00747 * end of file). 00748 * 00749 * Revision 1.57 2009-02-04 17:54:30 joergr 00750 * Fixed various layout and formatting issues. 00751 * 00752 * Revision 1.56 2009-02-04 14:05:01 onken 00753 * Introduced global flag that, if enabled, tells the parser to continue 00754 * parsing if possible. 00755 * 00756 * Revision 1.55 2009-01-29 15:36:16 onken 00757 * Added global parsing option that allows for reading private attributes in 00758 * implicit encoding having a maximum length to be read as sequences instead 00759 * of relying on the dictionary. 00760 * 00761 * Revision 1.54 2009-01-06 16:28:11 joergr 00762 * Reworked print() output format for option PF_showTreeStructure. 00763 * 00764 * Revision 1.53 2009-01-05 15:32:23 joergr 00765 * Added global flag that allows for reading incorrectly encoded DICOM datasets 00766 * where particular data elements are encoded with a differing transfer syntax 00767 * (Implicit VR Little endian instead of Explicit VR encoding as declared). 00768 * 00769 * Revision 1.52 2008-09-24 13:33:53 joergr 00770 * Fixed typo in comment. 00771 * 00772 * Revision 1.51 2008-07-17 11:19:49 onken 00773 * Updated copyFrom() documentation. 00774 * 00775 * Revision 1.50 2008-07-17 10:30:23 onken 00776 * Implemented copyFrom() method for complete DcmObject class hierarchy, which 00777 * permits setting an instance's value from an existing object. Implemented 00778 * assignment operator where necessary. 00779 * 00780 * Revision 1.49 2008-04-17 14:48:39 meichel 00781 * Method DcmObject::getLengthField now public, needed by dcmcheck 00782 * 00783 * Revision 1.48 2007/11/29 14:30:19 meichel 00784 * Write methods now handle large raw data elements (such as pixel data) 00785 * without loading everything into memory. This allows very large images to 00786 * be sent over a network connection, or to be copied without ever being 00787 * fully in memory. 00788 * 00789 * Revision 1.47 2007/06/29 14:17:49 meichel 00790 * Code clean-up: Most member variables in module dcmdata are now private, 00791 * not protected anymore. 00792 * 00793 * Revision 1.46 2007/02/19 15:04:34 meichel 00794 * Removed searchErrors() methods that are not used anywhere and added 00795 * error() methods only in the DcmObject subclasses where really used. 00796 * 00797 * Revision 1.45 2006/12/15 14:18:07 joergr 00798 * Added new method that checks whether a DICOM object or element is affected 00799 * by SpecificCharacterSet (0008,0005). 00800 * 00801 * Revision 1.44 2006/12/13 13:58:15 joergr 00802 * Added new optional parameter "checkAllStrings" to method containsExtended 00803 * Characters(). 00804 * 00805 * Revision 1.43 2006/08/15 15:49:56 meichel 00806 * Updated all code in module dcmdata to correctly compile when 00807 * all standard C++ classes remain in namespace std. 00808 * 00809 * Revision 1.42 2006/05/11 08:54:23 joergr 00810 * Moved checkForNonASCIICharacters() from application to library. 00811 * 00812 * Revision 1.41 2005/12/08 16:28:22 meichel 00813 * Changed include path schema for all DCMTK header files 00814 * 00815 * Revision 1.40 2005/12/02 08:49:17 joergr 00816 * Changed macro NO_XFER_DETECTION_FOR_DATASETS into a global option that can 00817 * be enabled and disabled at runtime. 00818 * 00819 * Revision 1.39 2005/11/24 12:50:57 meichel 00820 * Fixed bug in code that prepares a byte stream that is fed into the MAC 00821 * algorithm when creating or verifying a digital signature. The previous 00822 * implementation was non-conformant when signatures included compressed 00823 * (encapsulated) pixel data because the item length was included in the byte 00824 * stream, while it should not. The global variable dcmEnableOldSignatureFormat 00825 * and a corresponding command line option in dcmsign allow to re-enable the old 00826 * implementation. 00827 * 00828 * Revision 1.38 2005/05/10 15:27:14 meichel 00829 * Added support for reading UN elements with undefined length according 00830 * to CP 246. The global flag dcmEnableCP246Support allows to revert to the 00831 * prior behaviour in which UN elements with undefined length were parsed 00832 * like a normal explicit VR SQ element. 00833 * 00834 * Revision 1.37 2004/07/01 12:28:25 meichel 00835 * Introduced virtual clone method for DcmObject and derived classes. 00836 * 00837 * Revision 1.36 2004/04/27 09:21:01 wilkens 00838 * Fixed a bug in dcelem.cc which occurs when one is serializing a dataset 00839 * (that contains an attribute whose length value is coded with 2 bytes) into 00840 * a given buffer. Although the number of available bytes in the buffer was 00841 * sufficient, the dataset->write(...) method would always return 00842 * EC_StreamNotifyClient to indicate that there are not sufficient bytes 00843 * available in the buffer. This code modification fixes the problem. 00844 * 00845 * Revision 1.35 2003/06/12 13:33:21 joergr 00846 * Fixed inconsistent API documentation reported by Doxygen. 00847 * 00848 * Revision 1.34 2002/12/06 12:49:11 joergr 00849 * Enhanced "print()" function by re-working the implementation and replacing 00850 * the boolean "showFullData" parameter by a more general integer flag. 00851 * Added doc++ documentation. 00852 * Made source code formatting more consistent with other modules/files. 00853 * 00854 * Revision 1.33 2002/08/27 16:55:35 meichel 00855 * Initial release of new DICOM I/O stream classes that add support for stream 00856 * compression (deflated little endian explicit VR transfer syntax) 00857 * 00858 * Revision 1.32 2002/08/20 12:18:35 meichel 00859 * Changed parameter list of loadFile and saveFile methods in class 00860 * DcmFileFormat. Removed loadFile and saveFile from class DcmObject. 00861 * 00862 * Revision 1.31 2002/07/08 14:45:20 meichel 00863 * Improved dcmdata behaviour when reading odd tag length. Depending on the 00864 * global boolean flag dcmAcceptOddAttributeLength, the parser now either accepts 00865 * odd length attributes or implements the old behaviour, i.e. assumes a real 00866 * length larger by one. 00867 * 00868 * Revision 1.30 2002/04/25 09:38:47 joergr 00869 * Added support for XML output of DICOM objects. 00870 * 00871 * Revision 1.29 2002/04/11 12:23:46 joergr 00872 * Added new methods for loading and saving DICOM files. 00873 * 00874 * Revision 1.28 2001/11/16 15:54:39 meichel 00875 * Adapted digital signature code to final text of supplement 41. 00876 * 00877 * Revision 1.27 2001/09/25 17:19:27 meichel 00878 * Adapted dcmdata to class OFCondition 00879 * 00880 * Revision 1.26 2001/06/01 15:48:41 meichel 00881 * Updated copyright header 00882 * 00883 * Revision 1.25 2000/11/07 16:56:07 meichel 00884 * Initial release of dcmsign module for DICOM Digital Signatures 00885 * 00886 * Revision 1.24 2000/04/14 16:02:39 meichel 00887 * Global flag dcmEnableAutomaticInputDataCorrection now derived from OFGlobal 00888 * and, thus, safe for use in multi-thread applications. 00889 * 00890 * Revision 1.23 2000/03/08 16:26:16 meichel 00891 * Updated copyright header. 00892 * 00893 * Revision 1.22 2000/03/03 14:05:24 meichel 00894 * Implemented library support for redirecting error messages into memory 00895 * instead of printing them to stdout/stderr for GUI applications. 00896 * 00897 * Revision 1.21 2000/02/10 10:50:52 joergr 00898 * Added new feature to dcmdump (enhanced print method of dcmdata): write 00899 * pixel data/item value fields to raw files. 00900 * 00901 * Revision 1.20 2000/02/01 10:12:02 meichel 00902 * Avoiding to include <stdlib.h> as extern "C" on Borland C++ Builder 4, 00903 * workaround for bug in compiler header files. 00904 * 00905 * Revision 1.19 1999/03/31 09:24:42 meichel 00906 * Updated copyright header in module dcmdata 00907 * 00908 * 00909 */