DYT/Tool/3rdParty_x64/include/dcmtk/dcmdata/dcdirrec.h
2024-11-22 23:19:31 +08:00

533 lines
23 KiB
C++

/*
*
* Copyright (C) 1994-2016, OFFIS e.V.
* All rights reserved. See COPYRIGHT file for details.
*
* This software and supporting documentation were developed by
*
* OFFIS e.V.
* R&D Division Health
* Escherweg 2
* D-26121 Oldenburg, Germany
*
*
* Module: dcmdata
*
* Author: Gerd Ehlers, Andreas Barth
*
* Purpose: Interface of class DcmDirectoryRecord
*
*/
#ifndef DCDIRREC_H
#define DCDIRREC_H
#include "dcmtk/config/osconfig.h" /* make sure OS specific configuration is included first */
#include "dcmtk/dcmdata/dcitem.h"
#include "dcmtk/dcmdata/dcsequen.h"
#include "dcmtk/dcmdata/dcfilefo.h"
/// types of directory records in a DICOMDIR
typedef enum {
/// root
ERT_root = 0,
/// curve (retired)
ERT_Curve = 1,
/// film box (retired)
ERT_FilmBox = 2,
/// film session (retired)
ERT_FilmSession = 3,
/// image
ERT_Image = 4,
/// image box (retired)
ERT_ImageBox = 5,
/// interpretation (retired)
ERT_Interpretation = 6,
/// modality LUT (retired)
ERT_ModalityLut = 7,
/// MRDR (retired)
ERT_Mrdr = 8,
/// overlay (retired)
ERT_Overlay = 9,
/// patient
ERT_Patient = 10,
/// print queue (retired)
ERT_PrintQueue = 11,
/// private
ERT_Private = 12,
/// results
ERT_Results = 13,
/// series
ERT_Series = 14,
/// study
ERT_Study = 15,
/// study component (retired)
ERT_StudyComponent = 16,
/// topic (retired)
ERT_Topic = 17,
/// visit (retired)
ERT_Visit = 18,
/// VOI LUT (retired)
ERT_VoiLut = 19,
/// SR document
ERT_SRDocument = 20,
/// presentation state
ERT_Presentation = 21,
/// waveform
ERT_Waveform = 22,
/// RT dose
ERT_RTDose = 23,
/// RT structure set
ERT_RTStructureSet = 24,
/// RT plan
ERT_RTPlan = 25,
/// RT treatment record
ERT_RTTreatRecord = 26,
/// stored print (retired)
ERT_StoredPrint = 27,
/// key object selection document
ERT_KeyObjectDoc = 28,
/// registration
ERT_Registration = 29,
/// fiducial
ERT_Fiducial = 30,
/// raw data
ERT_RawData = 31,
/// spectroscopy
ERT_Spectroscopy = 32,
/// encapsulated document
ERT_EncapDoc = 33,
/// value map
ERT_ValueMap = 34,
/// hanging protocol
ERT_HangingProtocol = 35,
/// stereometric relationships
ERT_Stereometric = 36,
/// HL7 structured document
ERT_HL7StrucDoc = 37,
/// palette
ERT_Palette = 38,
/// surface
ERT_Surface = 39,
/// measurement
ERT_Measurement = 40,
/// implant
ERT_Implant = 41,
/// implant group
ERT_ImplantGroup = 42,
/// implant assembly
ERT_ImplantAssy = 43,
/// plan
ERT_Plan = 44,
/// surface scan
ERT_SurfaceScan = 45,
/// tractography
ERT_Tract = 46,
/// assessment
ERT_Assessment = 47
} E_DirRecType;
class DcmDicomDir;
/** a class representing a directory record dataset in a DICOMDIR.
*/
class DCMTK_DCMDATA_EXPORT DcmDirectoryRecord : public DcmItem
{
friend class DcmDicomDir;
public:
/// default constructor
DcmDirectoryRecord();
/** constructor
* @param tag attribute tag
* @param len length of the attribute value
*/
DcmDirectoryRecord(const DcmTag &tag,
const Uint32 len);
/** constructor
* @param recordType record type
* @param referencedFileID referenced file ID in DICOM format
* @param sourceFileName path to referenced file in operating system specific format
* @param fileFormat fileFormat for sourceFileName, can be NULL
*/
DcmDirectoryRecord(const E_DirRecType recordType,
const char *referencedFileID, // DICOM format with '\\'
const OFFilename &sourceFileName, // OS format
DcmFileFormat* fileFormat = NULL);
/** constructor
* @param recordTypeName record type as string
* @param referencedFileID referenced file ID in DICOM format
* @param sourceFileName path to referenced file in operating system specific format
* @param fileFormat fileFormat for sourceFileName, can be NULL
*/
DcmDirectoryRecord(const char *recordTypeName,
const char *referencedFileID, // DICOM format with '\\'
const OFFilename &sourceFileName, // OS format
DcmFileFormat* fileFormat = NULL);
/** copy constructor
* @param oldDirRec element to be copied
*/
DcmDirectoryRecord(const DcmDirectoryRecord &oldDirRec);
/** assignment operator
* @param obj the directory record to be copied
*/
DcmDirectoryRecord &operator=(const DcmDirectoryRecord &obj);
/// destructor
virtual ~DcmDirectoryRecord();
/** clone method
* @return deep copy of this object
*/
virtual DcmObject *clone() const
{
return new DcmDirectoryRecord(*this);
}
/** Virtual object copying. This method can be used for DcmObject
* and derived classes to get a deep copy of an object. Internally
* the assignment operator is called if the given DcmObject parameter
* is of the same type as "this" object instance. If not, an error
* is returned. This function permits copying an object by value
* in a virtual way which therefore is different to just calling the
* assignment operator of DcmElement which could result in slicing
* the object.
* @param rhs - [in] The instance to copy from. Has to be of the same
* class type as "this" object
* @return EC_Normal if copying was successful, error otherwise
*/
virtual OFCondition copyFrom(const DcmObject& rhs);
/** return identifier for this class. Every class derived from this class
* returns a unique value of type enum DcmEVR for this call. This is used
* as a "poor man's RTTI" to correctly identify instances derived from
* this class even on compilers not supporting RTTI.
* @return type identifier of this class
*/
virtual DcmEVR ident() const;
/// returns current status flag
inline OFCondition error() const { return errorFlag; }
/** mode specifying whether the SpecificCharacterSet (0008,0005) element should be
* checked by convertCharacterSet() or not, i.e.\ whether this element might be
* present on this dataset-level.
* @return always returns OFTrue, i.e.\ SpecificCharacterSet should be checked
*/
virtual OFBool checkForSpecificCharacterSet() const { return OFTrue; }
/** convert all element values that are contained in this record and that are
* affected by SpecificCharacterSet from the given source character set to the given
* destination character set. The defined terms for a particular character set can
* be found in the DICOM standard, e.g. "ISO_IR 100" for ISO 8859-1 (Latin 1) or
* "ISO_IR 192" for Unicode in UTF-8. An empty string denotes the default character
* repertoire, which is ASCII (7-bit). If multiple values are given for 'fromCharset'
* (separated by a backslash) code extension techniques are used and escape sequences
* may be encountered in the source string to switch between the specified character
* sets.
* @param fromCharset name of the source character set(s) used for the conversion
* @param toCharset name of the destination character set used for the conversion.
* Only a single value is permitted (i.e. no code extensions).
* @param transliterate mode specifying whether a character that cannot be
* represented in the destination character encoding is approximated through one
* or more characters that look similar to the original one
* @param updateCharset if OFTrue, the SpecificCharacterSet (0008,0005) element is
* updated, i.e.\ the current value is either replaced or a new element is inserted
* or the existing element is deleted. If OFFalse the SpecificCharacterSet element
* remains unchanged.
* @param discardIllegal mode specifying whether characters that cannot be represented
* in the destination character encoding will be silently discarded
* @return status, EC_Normal if successful, an error code otherwise
*/
virtual OFCondition convertCharacterSet(const OFString &fromCharset,
const OFString &toCharset,
const OFBool transliterate = OFFalse,
const OFBool updateCharset = OFFalse,
const OFBool discardIllegal = OFFalse);
/** convert all element values that are contained in this record and that are
* affected by SpecificCharacterSet to the given destination character set. If not
* disabled, the source character set is determined automatically from the value of
* the SpecificCharacterSet (0008,0005) element. The defined terms for the
* destination character set can be found in the DICOM standard, e.g. "ISO_IR 100"
* for ISO 8859-1 (Latin 1) or "ISO_IR 192" for Unicode in UTF-8. An empty string
* denotes the default character repertoire, which is ASCII (7-bit).
* @param toCharset name of the destination character set used for the conversion.
* Only a single value is permitted (i.e. no code extensions).
* @param transliterate mode specifying whether a character that cannot be
* represented in the destination character encoding is approximated through one
* or more characters that look similar to the original one
* @param ignoreCharset if OFTrue, the value of SpecificCharacterSet is ignored.
* Also see checkForSpecificCharacterSet().
* @param discardIllegal mode specifying whether characters that cannot be represented
* in the destination character encoding will be silently discarded
* @return status, EC_Normal if successful, an error code otherwise
*/
virtual OFCondition convertCharacterSet(const OFString &toCharset,
const OFBool transliterate = OFFalse,
const OFBool ignoreCharset = OFFalse,
const OFBool discardIllegal = OFFalse);
/** convert all element values that are contained in this record and that are
* affected by SpecificCharacterSet from the currently selected source character
* set to the currently selected destination character set. Since the Basic
* Directory IOD, which specifies the structure and content of a DICOMDIR, does not
* contain the SpecificCharacterSet (0008,0005) element in the main dataset but in
* each directory record, this method also checks for this element and creates a new
* character set converter for the contained data elements (if needed).
* @param converter character set converter to be used to convert the element values
* @return status, EC_Normal if successful, an error code otherwise
*/
virtual OFCondition convertCharacterSet(DcmSpecificCharacterSet &converter);
/** print all elements of the item to a stream
* @param out output stream
* @param flags optional flag used to customize the output (see DCMTypes::PF_xxx)
* @param level current level of nested items. Used for indentation.
* @param pixelFileName not used
* @param pixelCounter not used
*/
virtual void print(STD_NAMESPACE ostream&out,
const size_t flags = 0,
const int level = 0,
const char *pixelFileName = NULL,
size_t *pixelCounter = NULL);
/** This function reads the information of all attributes which
* are captured in the input stream and captures this information
* in elementList. Each attribute is represented as an element
* in this list. If not all information for an attribute could be
* read from the stream, the function returns EC_StreamNotifyClient.
* @param inStream The stream which contains the information.
* @param xfer The transfer syntax which was used to encode
* the information in inStream.
* @param glenc Encoding type for group length; specifies
* what will be done with group length tags.
* @param maxReadLength Maximum read length for reading an attribute value.
* @return status, EC_Normal if successful, an error code otherwise
*/
virtual OFCondition read(DcmInputStream & inStream,
const E_TransferSyntax xfer,
const E_GrpLenEncoding glenc = EGL_noChange,
const Uint32 maxReadLength = DCM_MaxReadLength);
/** write object in XML format
* @param out output stream to which the XML document is written
* @param flags optional flag used to customize the output (see DCMTypes::XF_xxx)
* @return status, EC_Normal if successful, an error code otherwise
*/
virtual OFCondition writeXML(STD_NAMESPACE ostream&out,
const size_t flags = 0);
/** check the currently stored element value
* @param autocorrect correct value length if OFTrue
* @return status, EC_Normal if value length is correct, an error code otherwise
*/
virtual OFCondition verify(const OFBool autocorrect = OFFalse);
/** a complex, stack-based, hierarchical search method. It allows for a search
* for a DICOM object with a given attribute within a given container,
* hierarchically, from a starting position identified through a cursor stack.
* @param xtag the DICOM attribute tag we are searching for
* @param resultStack depending on the search mode (see below), this parameter
* either serves as an input and output parameter, or as an output parameter
* only (the latter being the default). When used as an input parameter,
* the cursor stack defines the start position for the search within a
* hierarchical DICOM dataset. Upon successful return, the stack contains
* the position of the element found, in the form of a pointer to each dataset,
* sequence, item and element from the main dataset down to the found element.
* @param mode search mode, controls how the search stack is handled.
* In the default mode, ESM_fromHere, the stack is ignored on input, and
* the search starts in the object for which this method is called.
* In the other modes, the stack is used both as an input and an output
* parameter and defines the starting point for the search.
* @param searchIntoSub if true, the search will be performed hierarchically descending
* into the sequences and items of the dataset. If false, only the current container
* (sequence or item) will be traversed.
* @return EC_Normal if found, EC_TagNotFound if not found, an error code is something went wrong.
*/
virtual OFCondition search(const DcmTagKey &xtag, // in
DcmStack &resultStack, // inout
E_SearchMode mode = ESM_fromHere, // in
OFBool searchIntoSub = OFTrue); // in
/// get record type of this directory record
virtual E_DirRecType getRecordType();
/** if this directory record references an MRDR (multi-reference directory record),
* return pointer to the MRDR referenced by this object.
* @return pointer to MRDR referenced by this object or NULL of no MRDR referenced
*/
virtual DcmDirectoryRecord* getReferencedMRDR();
/** create a reference from this record to an MRDR
* @param mrdr pointer to MRDR
* @return EC_Normal upon success, an error code otherwise
*/
virtual OFCondition assignToMRDR(DcmDirectoryRecord *mrdr ); // in
/** open a DICOM file and make this directory record into a directory
* record for that DICOM file. The most relevant record keys
* (SOP Class UID, SOP instance UID, Transfer Syntax UID) are inserted
* into the directory record.
* @param referencedFileID referenced file ID in DICOM format
* @param sourceFileName path to file in operating system specific format
* @return EC_Normal upon success, an error code otherwise
*/
virtual OFCondition assignToSOPFile(const char *referencedFileID,
const OFFilename &sourceFileName);
/// return number of directory records that are child record of this one
virtual unsigned long cardSub() const;
/** insert a child directory record
* @param dirRec directory record to be inserted. Must be allocated on heap, ownership is
* transferred to this object
* @param where index where to insert object
* @param before flag indicating whether to insert the record before or after the element
* identified by where
* @return EC_Normal upon success, an error code otherwise
*/
virtual OFCondition insertSub(DcmDirectoryRecord* dirRec,
unsigned long where = DCM_EndOfListIndex,
OFBool before = OFFalse);
/** insert new directory child record at the current position.
* The current position is stored internally in the 'lowerLevelList' member variable.
* @param dirRec new child record to be inserted
* @param before flag indicating whether to insert the record before (OFFalse) or
* after (OFTrue) the current position
* @return status, EC_Normal upon success, an error code otherwise
*/
virtual OFCondition insertSubAtCurrentPos(DcmDirectoryRecord *dirRec,
OFBool before = OFFalse);
/** access child directory record. Returns a pointer to the object maintained
* as a child, not a copy.
* @param num index, must be < cardSub()
* @return pointer to child directory record or NULL if not found
*/
virtual DcmDirectoryRecord* getSub(const unsigned long num);
/** get next directory child record starting at a given record
* @param dirRec record to start from (goto first record if NULL)
* @return pointer to next record if successful, NULL otherwise
*/
virtual DcmDirectoryRecord* nextSub(const DcmDirectoryRecord *dirRec);
/** remove child directory record. If found, the record is not deleted but
* returned to the caller who is responsible for further management of the
* DcmDirectoryRecord object.
* @param num index number of element, must be < cardSub()
* @return pointer to DcmDirectoryRecord if found, NULL otherwise
*/
virtual DcmDirectoryRecord* removeSub(const unsigned long num);
/** remove child directory record. If found, the record is not deleted but
* returned to the caller who is responsible for further management of the
* DcmDirectoryRecord object.
* @param dirRec pointer to element to be removed from list
* @return pointer to element if found, NULL otherwise
*/
virtual DcmDirectoryRecord* removeSub(DcmDirectoryRecord *dirRec);
/** remove child directory record and delete file referenced by that record, if any
* @param num index number of element, must be < cardSub()
* @return status, EC_Normal upon success, an error code otherwise
*/
virtual OFCondition deleteSubAndPurgeFile(const unsigned long num);
/** remove child directory record and delete file referenced by that record, if any
* @param dirRec pointer to element to be removed from list
* @return status, EC_Normal upon success, an error code otherwise
*/
virtual OFCondition deleteSubAndPurgeFile(DcmDirectoryRecord *dirRec);
/// revert the list of child directory records to default constructed (empty) state
virtual OFCondition clearSub();
/** store the filename from which this directory record was read from
* @param fname filename, must not be empty
*/
virtual void setRecordsOriginFile(const OFFilename &fname);
/// get the filename from which this directory record was read from, empty if not set
virtual const OFFilename &getRecordsOriginFile();
/// get the offset in file of this directory record
Uint32 getFileOffset() const;
protected:
// side-effect-free conversion routines:
E_DirRecType recordNameToType(const char *recordTypeName);
char* buildFileName(const char *origName, char *destName);
OFCondition checkHierarchy(const E_DirRecType upperRecord,
const E_DirRecType lowerRecord);
// access to data elements within the Directory Records:
OFCondition setRecordType(E_DirRecType newType);
E_DirRecType lookForRecordType();
OFCondition setReferencedFileID( const char *referencedFileID);
const char* lookForReferencedFileID();
DcmDirectoryRecord* lookForReferencedMRDR();
const char* getReferencedFileName(); // local or in MRDR
OFCondition setRecordInUseFlag(const Uint16 newFlag);
Uint16 lookForRecordInUseFlag();
Uint32 setFileOffset(Uint32 position);
// access to MRDR data element:
OFCondition setNumberOfReferences(Uint32 newRefNum);
Uint32 lookForNumberOfReferences();
Uint32 increaseRefNum();
Uint32 decreaseRefNum();
// misc:
/** Load all necessary info for this directory record.
* @param referencedFileID file ID that is being referenced, may be NULL
* @param sourceFileName filename for the DICOM file, may be empty (unspecified)
* @param fileFormat If not NULL, then this should be the result of loading
* sourceFileName. May only be non-NULL if sourceFileName isn't empty.
*/
OFCondition fillElementsAndReadSOP(const char *referencedFileID,
const OFFilename &sourceFileName,
DcmFileFormat *fileFormat = NULL);
OFCondition masterInsertSub(DcmDirectoryRecord *dirRec,
const unsigned long where = DCM_EndOfListIndex);
OFCondition purgeReferencedFile();
private:
/// filename (path) of the file from which this directory record was read
OFFilename recordsOriginFile;
/// list of child directory records, kept in a sequence of items
DcmSequenceOfItems *lowerLevelList;
/// directory record type of this record
E_DirRecType DirRecordType;
/// pointer to multi-referenced directory record (MRDR) if this record refers to one, NULL otherwise
DcmDirectoryRecord *referencedMRDR;
/// number of other directory records referring to this one; used for MRDR records
Uint32 numberOfReferences;
/// byte offset at which the start of this directory record resides in the file from which it was read
Uint32 offsetInFile;
};
#endif // DCDIRREC_H