#include <gdcmDocument.h>
Inheritance diagram for gdcm::Document:
Public Types | |
typedef std::list< Element > | ListElements |
Public Member Functions | |
Dict * | GetPubDict () |
Get the public dictionary used. | |
Dict * | GetShaDict () |
Get the shadow dictionary used. | |
bool | SetShaDict (Dict *dict) |
Set the shadow dictionary used. | |
bool | SetShaDict (DictKey const &dictName) |
Set the shadow dictionary used. | |
virtual bool | IsReadable () |
This predicate, based on hopefully reasonable heuristics, decides whether or not the current Document was properly parsed and contains the mandatory information for being considered as a well formed and usable Dicom/Acr File. | |
bool | IsDicomV3 () |
Predicate for dicom version 3 file. | |
bool | IsPapyrus () |
Predicate for Papyrus file Dedicated to whomsoever it may concern. | |
FileType | GetFileType () |
returns the File Type (ACR, ACR_LIBIDO, ExplicitVR, ImplicitVR, Unknown) | |
std::string | GetTransferSyntax () |
Accessor to the Transfer Syntax (when present) of the current document (it internally handles reading the value from disk when only parsing occured). | |
std::string | GetTransferSyntaxName () |
Accesses the info from 0002,0010 : Transfer Syntax and TS. | |
int | GetSwapCode () |
'Swap code' accessor (see SwapCode ) | |
uint16_t | SwapShort (uint16_t) |
Swaps the bytes so they agree with the processor order. | |
uint32_t | SwapLong (uint32_t) |
Swaps back the bytes of 4-byte long integer accordingly to processor order. | |
uint16_t | UnswapShort (uint16_t a) |
Unswaps back the bytes of 2-bytes long integer so they agree with the processor order. | |
uint32_t | UnswapLong (uint32_t a) |
Unswaps back the bytes of 4-byte long integer so they agree with the processor order. | |
const std::string & | GetFileName () const |
Accessor to Filename. | |
void | SetFileName (std::string const &fileName) |
Accessor to Filename. | |
std::ifstream * | OpenFile () |
Tries to open the file Document::Filename and checks the preamble when existing. | |
bool | CloseFile () |
closes the file | |
void | WriteContent (std::ofstream *fp, FileType type) |
Writes in a file all the Header Entries (Dicom Elements). | |
virtual void | LoadEntryBinArea (uint16_t group, uint16_t elem) |
Loads (from disk) the element content when a string is not suitable. | |
virtual void | LoadEntryBinArea (BinEntry *entry) |
Loads (from disk) the element content when a string is not suitable. | |
void | LoadDocEntrySafe (DocEntry *entry) |
Loads the element while preserving the current underlying file position indicator as opposed to LoadDocEntry that modifies it. | |
bool | operator< (Document &document) |
Compares two documents, according to DicomDir rules. | |
virtual void | Print (std::ostream &os=std::cout, std::string const &indent="") |
Prints the Header Entries (Dicom Elements) from the H Table. | |
bool | AddEntry (DocEntry *Entry) |
add a new Dicom Element pointer to the H Table | |
bool | RemoveEntry (DocEntry *EntryToRemove) |
Clear the hash table from given entry AND delete the entry. | |
bool | RemoveEntryNoDestroy (DocEntry *EntryToRemove) |
Clear the hash table from given entry BUT keep the entry. | |
void | ClearEntry () |
delete all entries in the ElementSet | |
DocEntry * | GetFirstEntry () |
Get the first entry while visiting *the* 'zero level' DocEntrySet (DocEntries out of any Sequence). | |
DocEntry * | GetNextEntry () |
Get the next entry while visiting *the* 'zero level' DocEntrySet (DocEntries out of any Sequence). | |
DocEntry * | GetDocEntry (uint16_t group, uint16_t elem) |
retrieves a Dicom Element using (group, element) | |
bool | IsEmpty () |
Tells us if the ElementSet contains no entry. | |
virtual std::string | GetEntryValue (uint16_t group, uint16_t elem) |
Get the "std::string representable" value of the Dicom entry. | |
virtual void * | GetEntryBinArea (uint16_t group, uint16_t elem) |
Gets (from Header) a 'non string' element value. | |
virtual int | GetEntryLength (uint16_t group, uint16_t elem) |
Searches within Header Entries (Dicom Elements) parsed with the public and private dictionaries for the value length of a given tag.. | |
virtual std::string | GetEntryVR (uint16_t group, uint16_t elem) |
Searches within Header Entries (Dicom Elements) parsed with the public [and private dictionaries] for the element value representation of a given tag.. Obtaining the VR (Value Representation) might be needed by caller to convert the string typed content to caller's native type (think of C++ vs Python). The VR is actually of a higher level of semantics than just the native C++ type. | |
ValEntry * | GetValEntry (uint16_t group, uint16_t elem) |
Same as Document::GetDocEntry except it only returns a result when the corresponding entry is of type ValEntry. | |
BinEntry * | GetBinEntry (uint16_t group, uint16_t elem) |
Same as Document::GetDocEntry except it only returns a result when the corresponding entry is of type BinEntry. | |
SeqEntry * | GetSeqEntry (uint16_t group, uint16_t elem) |
Same as Document::GetDocEntry except it only returns a result when the corresponding entry is of type SeqEntry. | |
bool | SetValEntry (std::string const &content, uint16_t group, uint16_t elem) |
Accesses an existing DocEntry (i.e. a Dicom Element) through it's (group, element) and modifies it's content with the given value. | |
bool | SetValEntry (std::string const &content, ValEntry *entry) |
Accesses an existing DocEntry (i.e. a Dicom Element) and modifies it's content with the given value. | |
bool | SetBinEntry (uint8_t *content, int lgth, uint16_t group, uint16_t elem) |
Accesses an existing DocEntry (i.e. a Dicom Element) through it's (group, element) and modifies it's content with the given value. | |
bool | SetBinEntry (uint8_t *content, int lgth, BinEntry *entry) |
Accesses an existing BinEntry (i.e. a Dicom Element) and modifies it's content with the given value. | |
ValEntry * | InsertValEntry (std::string const &value, uint16_t group, uint16_t elem, TagName const &vr=GDCM_UNKNOWN) |
Modifies the value of a given Doc Entry (Dicom Element) when it exists. Create it with the given value when unexistant. | |
BinEntry * | InsertBinEntry (uint8_t *binArea, int lgth, uint16_t group, uint16_t elem, TagName const &vr=GDCM_UNKNOWN) |
Modifies the value of a given Header Entry (Dicom Element) when it exists. Create it with the given value when unexistant. A copy of the binArea is made to be kept in the Document. | |
SeqEntry * | InsertSeqEntry (uint16_t group, uint16_t elem) |
Modifies the value of a given Doc Entry (Dicom Element) when it exists. Creates it when unexistant. | |
virtual bool | CheckIfEntryExist (uint16_t group, uint16_t elem) |
Checks if a given Dicom Element exists within the H table. | |
ValEntry * | NewValEntry (uint16_t group, uint16_t elem, TagName const &vr=GDCM_UNKNOWN) |
Build a new Val Entry from all the low level arguments. Check for existence of dictionary entry, and build a default one when absent. | |
BinEntry * | NewBinEntry (uint16_t group, uint16_t elem, TagName const &vr=GDCM_UNKNOWN) |
Build a new Bin Entry from all the low level arguments. Check for existence of dictionary entry, and build a default one when absent. | |
SeqEntry * | NewSeqEntry (uint16_t group, uint16_t elem) |
Build a new Seq Entry from all the low level arguments. Check for existence of dictionary entry, and build a default one when absent. | |
DictEntry * | NewVirtualDictEntry (uint16_t group, uint16_t elem, TagName const &vr=GDCM_UNKNOWN, TagName const &vm=GDCM_UNKNOWN, TagName const &name=GDCM_UNKNOWN) |
Request a new virtual dict entry to the dict set. | |
void | SetPrintLevel (int level) |
Sets the print level for the Dicom Header Elements. | |
int | GetPrintLevel () |
Gets the print level for the Dicom Entries. | |
Protected Member Functions | |
Document () | |
This default constructor doesn't parse the file. You should then invoke Document::SetFileName and then the parsing. | |
Document (std::string const &filename) | |
constructor | |
virtual | ~Document () |
Canonical destructor. | |
uint16_t | ReadInt16 () throw ( FormatError ) |
Reads a supposed to be 16 Bits integer (swaps it depending on processor endianness). | |
uint32_t | ReadInt32 () throw ( FormatError ) |
Reads a supposed to be 32 Bits integer (swaps it depending on processor endianness). | |
void | SkipBytes (uint32_t) |
skips bytes inside the source file | |
int | ComputeGroup0002Length (FileType filetype) |
Re-computes the length of a ACR-NEMA/Dicom group from a DcmHeader. | |
DictEntry * | GetDictEntry (uint16_t group, uint16_t elem) |
Searches [both] the public [and the shadow dictionary (when they exist)] for the presence of the DictEntry with given group and element. The public dictionary has precedence on the shadow one. | |
DictEntry * | GetDictEntry (uint16_t group, uint16_t elem, TagName const &vr) |
Searches [both] the public [and the shadow dictionary (when they exist)] for the presence of the DictEntry with given group and element, and create a new virtual DictEntry if necessary. | |
Protected Attributes | |
std::string | Filename |
Refering underlying filename. | |
int | SwapCode |
Swap code gives an information on the byte order of a supposed to be an int32, as it's read on disc (depending on the image Transfer Syntax *and* on the processor endianess) as opposed as it should in memory to be dealt as an int32. For instance :
| |
bool | Group0002Parsed |
whether we already parsed group 0002 (Meta Elements) | |
bool | HasDCMPreamble |
whether file has a DCM Preamble | |
std::ifstream * | Fp |
File Pointer, opened during Document parsing. | |
FileType | Filetype |
ACR, ACR_LIBIDO, ExplicitVR, ImplicitVR, Unknown. | |
ListElements | AnonymizeList |
List of element to Anonymize. | |
int | PrintLevel |
Amount of printed details for each Dicom Entries : 0 : stands for the least detail level. | |
Static Protected Attributes | |
const unsigned int | HEADER_LENGTH_TO_READ |
After opening the file, we read HEADER_LENGTH_TO_READ bytes. | |
const unsigned int | MAX_SIZE_LOAD_ELEMENT_VALUE = 0xfff |
Elements whose value is longer than MAX_SIZE_LOAD_ELEMENT_VALUE are NOT loaded. | |
const unsigned int | MAX_SIZE_PRINT_ELEMENT_VALUE = 0x7fffffff |
Elements whose value is longer than MAX_SIZE_PRINT_ELEMENT_VALUE are NOT printed. | |
Private Member Functions | |
void | Initialize () |
Loads all the needed Dictionaries. | |
void | ParseDES (DocEntrySet *set, long offset, long l_max, bool delim_mode) |
Parses a DocEntrySet (Zero-level DocEntries or SQ Item DocEntries). | |
void | ParseSQ (SeqEntry *seq, long offset, long l_max, bool delim_mode) |
Parses a Sequence ( SeqEntry after SeqEntry). | |
void | LoadDocEntry (DocEntry *e) |
Loads the element content if its length doesn't exceed the value specified with Document::SetMaxSizeLoadEntry(). | |
void | FindDocEntryLength (DocEntry *e) throw ( FormatError ) |
Find the value Length of the passed Header Entry. | |
uint32_t | FindDocEntryLengthOBOrOW () throw ( FormatUnexpected ) |
Find the Length till the next sequence delimiter. | |
std::string | FindDocEntryVR () |
Find the Value Representation of the current Dicom Element. | |
bool | CheckDocEntryVR (VRKey k) |
Check the correspondance between the VR of the header entry and the taken VR. If they are different, the header entry is updated with the new VR. | |
std::string | GetDocEntryValue (DocEntry *entry) |
Get the transformed value of the header entry. The VR value is used to define the transformation to operate on the value. | |
std::string | GetDocEntryUnvalue (DocEntry *entry) |
Get the reverse transformed value of the header entry. The VR value is used to define the reverse transformation to operate on the value. | |
void | SkipDocEntry (DocEntry *entry) |
Skip a given Header Entry. | |
void | SkipToNextDocEntry (DocEntry *entry) |
Skips to the beginning of the next Header Entry. | |
void | FixDocEntryFoundLength (DocEntry *entry, uint32_t l) |
When the length of an element value is obviously wrong (because the parser went Jabberwocky) one can hope improving things by applying some heuristics. | |
bool | IsDocEntryAnInteger (DocEntry *entry) |
Apply some heuristics to predict whether the considered element value contains/represents an integer or not. | |
bool | CheckSwap () |
Discover what the swap code is (among little endian, big endian, bad little endian, bad big endian). sw is set. | |
void | SwitchByteSwapCode () |
Change the Byte Swap code. | |
void | SetMaxSizeLoadEntry (long) |
during parsing, Header Elements too long are not loaded in memory | |
void | SetMaxSizePrintEntry (long) |
Header Elements too long will not be printed. | |
DocEntry * | ReadNextDocEntry () |
Read the next tag but WITHOUT loading it's value (read the 'Group Number', the 'Element Number', gets the Dict Entry gets the VR, gets the length, gets the offset value). | |
void | HandleBrokenEndian (uint16_t &group, uint16_t &elem) |
Handle broken private tag from Philips NTSCAN where the endianess is being switch to BigEndian for no apparent reason. | |
void | HandleOutOfGroup0002 (uint16_t &group, uint16_t &elem) |
Group 0002 is always coded Little Endian whatever Transfer Syntax is. | |
Private Attributes | |
Dict * | RefPubDict |
Public dictionary used to parse this header. | |
Dict * | RefShaDict |
Optional "shadow dictionary" (private elements) used to parse this header. | |
uint32_t | MaxSizeLoadEntry |
Size threshold above which an element value will NOT be loaded in memory (to avoid loading the image/volume itself). By default, this upper bound is fixed to 1024 bytes (which might look reasonable when one considers the definition of the various VR contents). | |
uint32_t | MaxSizePrintEntry |
Size threshold above which an element value will NOT be *printed* in order no to polute the screen output. By default, this upper bound is fixed to 64 bytes. |
Definition at line 43 of file gdcmDocument.h.
|
Definition at line 47 of file gdcmDocument.h. |
|
This default constructor doesn't parse the file. You should then invoke Document::SetFileName and then the parsing.
Definition at line 157 of file gdcmDocument.cxx. References gdcm::ExplicitVR, Filetype, Fp, Group0002Parsed, Initialize(), MAX_SIZE_LOAD_ELEMENT_VALUE, SetMaxSizeLoadEntry(), and SwapCode.
00158 :ElementSet(-1) 00159 { 00160 Fp = 0; 00161 00162 SetMaxSizeLoadEntry(MAX_SIZE_LOAD_ELEMENT_VALUE); 00163 Initialize(); 00164 SwapCode = 1234; 00165 Filetype = ExplicitVR; 00166 Group0002Parsed = false; 00167 } |
|
constructor
FIXME FIXME FIXME The tags refered by the three following lines used to be CORRECTLY defined as having an US Value Representation in the public dictionary. BUT the semantics implied by the three following lines state that the corresponding tag contents are in fact the ones of a BinEntry. In order to fix things "Quick and Dirty" the dictionary was altered on PURPOSE but now contains a WRONG value. In order to fix things and restore the dictionary to its correct value, one needs to decided of the semantics by deciding whether the following tags are either:
Definition at line 61 of file gdcmDocument.cxx. References gdcm::ACR_LIBIDO, CheckSwap(), CloseFile(), Filetype, Fp, gdcmWarningMacro, gdcm::DocEntrySet::GetEntryValue(), Group0002Parsed, Initialize(), LoadEntryBinArea(), MAX_SIZE_LOAD_ELEMENT_VALUE, OpenFile(), ParseDES(), SetMaxSizeLoadEntry(), and gdcm::DocEntrySet::SetValEntry().
00062 :ElementSet(-1) 00063 { 00064 SetMaxSizeLoadEntry(MAX_SIZE_LOAD_ELEMENT_VALUE); 00065 Filename = filename; 00066 Initialize(); 00067 00068 Fp = 0; 00069 if ( !OpenFile() ) 00070 { 00071 return; 00072 } 00073 00074 Group0002Parsed = false; 00075 00076 gdcmWarningMacro( "Starting parsing of file: " << Filename.c_str()); 00077 00078 Fp->seekg(0, std::ios::end); 00079 long lgt = Fp->tellg(); 00080 00081 Fp->seekg(0, std::ios::beg); 00082 00083 CheckSwap(); 00084 long beg = Fp->tellg(); 00085 lgt -= beg; 00086 00087 ParseDES( this, beg, lgt, false); // Loading is done during parsing 00088 00089 Fp->seekg( 0, std::ios::beg); 00090 00091 // Load 'non string' values 00092 00093 std::string PhotometricInterpretation = GetEntryValue(0x0028,0x0004); 00094 if( PhotometricInterpretation == "PALETTE COLOR " ) 00095 { 00096 LoadEntryBinArea(0x0028,0x1200); // gray LUT 00112 LoadEntryBinArea(0x0028,0x1201); // R LUT 00113 LoadEntryBinArea(0x0028,0x1202); // G LUT 00114 LoadEntryBinArea(0x0028,0x1203); // B LUT 00115 00116 // Segmented Red Palette Color LUT Data 00117 LoadEntryBinArea(0x0028,0x1221); 00118 // Segmented Green Palette Color LUT Data 00119 LoadEntryBinArea(0x0028,0x1222); 00120 // Segmented Blue Palette Color LUT Data 00121 LoadEntryBinArea(0x0028,0x1223); 00122 } 00123 //FIXME later : how to use it? 00124 LoadEntryBinArea(0x0028,0x3006); //LUT Data (CTX dependent) 00125 00126 CloseFile(); 00127 00128 // ---------------------------- 00129 // Specific code to allow gdcm to read ACR-LibIDO formated images 00130 // Note: ACR-LibIDO is an extension of the ACR standard that was 00131 // used at CREATIS. For the time being (say a couple years) 00132 // we keep this kludge to allow a smooth move to gdcm for 00133 // CREATIS developpers (sorry folks). 00134 // 00135 // if recognition code tells us we deal with a LibIDO image 00136 // we switch lineNumber and columnNumber 00137 // 00138 std::string RecCode; 00139 RecCode = GetEntryValue(0x0008, 0x0010); // recognition code (RET) 00140 if (RecCode == "ACRNEMA_LIBIDO_1.1" || 00141 RecCode == "CANRME_AILIBOD1_1." ) // for brain-damaged softwares 00142 // with "little-endian strings" 00143 { 00144 Filetype = ACR_LIBIDO; 00145 std::string rows = GetEntryValue(0x0028, 0x0010); 00146 std::string columns = GetEntryValue(0x0028, 0x0011); 00147 SetValEntry(columns, 0x0028, 0x0010); 00148 SetValEntry(rows , 0x0028, 0x0011); 00149 } 00150 // --- End of ACR-LibIDO kludge --- 00151 } |
|
Canonical destructor.
Definition at line 172 of file gdcmDocument.cxx. References RefPubDict, and RefShaDict.
00173 { 00174 RefPubDict = NULL; 00175 RefShaDict = NULL; 00176 } |
|
add a new Dicom Element pointer to the H Table
Implements gdcm::DocEntrySet. Definition at line 69 of file gdcmElementSet.cxx. References gdcmWarningMacro, gdcm::DocEntry::GetKey(), gdcm::ElementSet::TagHT, and gdcm::TagKey. Referenced by gdcm::File::File(), gdcm::DocEntryArchive::Push(), and gdcm::DocEntryArchive::Restore().
00070 { 00071 const TagKey &key = newEntry->GetKey(); 00072 00073 if( TagHT.count(key) == 1 ) 00074 { 00075 gdcmWarningMacro( "Key already present: " << key.c_str()); 00076 return false; 00077 } 00078 else 00079 { 00080 TagHT.insert(TagDocEntryHT::value_type(newEntry->GetKey(), newEntry)); 00081 return true; 00082 } 00083 } |
|
Check the correspondance between the VR of the header entry and the taken VR. If they are different, the header entry is updated with the new VR.
Definition at line 1439 of file gdcmDocument.cxx. References gdcm::VRKey. Referenced by FindDocEntryVR().
01440 { 01441 if ( !Global::GetVR()->IsValidVR(vr) ) 01442 return false; 01443 01444 return true; 01445 } |
|
Checks if a given Dicom Element exists within the H table.
Definition at line 434 of file gdcmDocEntrySet.cxx. References gdcm::DocEntrySet::GetDocEntry().
00435 { 00436 return GetDocEntry(group,elem)!=NULL; 00437 } |
|
Discover what the swap code is (among little endian, big endian, bad little endian, bad big endian). sw is set.
Definition at line 1725 of file gdcmDocument.cxx. References gdcm::ACR, gdcm::ExplicitVR, Filetype, Fp, gdcmWarningMacro, gdcm::ImplicitVR, SwapCode, and gdcm::Unknown. Referenced by Document().
01726 { 01727 // The only guaranted way of finding the swap code is to find a 01728 // group tag since we know it's length has to be of four bytes i.e. 01729 // 0x00000004. Finding the swap code in then straigthforward. Trouble 01730 // occurs when we can't find such group... 01731 01732 uint32_t x = 4; // x : for ntohs 01733 bool net2host; // true when HostByteOrder is the same as NetworkByteOrder 01734 uint32_t s32; 01735 uint16_t s16; 01736 01737 char deb[256]; 01738 01739 // First, compare HostByteOrder and NetworkByteOrder in order to 01740 // determine if we shall need to swap bytes (i.e. the Endian type). 01741 if ( x == ntohs(x) ) 01742 { 01743 net2host = true; 01744 } 01745 else 01746 { 01747 net2host = false; 01748 } 01749 01750 // The easiest case is the one of a 'true' DICOM header, we just have 01751 // to look for the string "DICM" inside the file preamble. 01752 Fp->read(deb, 256); 01753 01754 char *entCur = deb + 128; 01755 if( memcmp(entCur, "DICM", (size_t)4) == 0 ) 01756 { 01757 gdcmWarningMacro( "Looks like DICOM Version3 (preamble + DCM)" ); 01758 01759 // Group 0002 should always be VR, and the first element 0000 01760 // Let's be carefull (so many wrong headers ...) 01761 // and determine the value representation (VR) : 01762 // Let's skip to the first element (0002,0000) and check there if we find 01763 // "UL" - or "OB" if the 1st one is (0002,0001) -, 01764 // in which case we (almost) know it is explicit VR. 01765 // WARNING: if it happens to be implicit VR then what we will read 01766 // is the length of the group. If this ascii representation of this 01767 // length happens to be "UL" then we shall believe it is explicit VR. 01768 // We need to skip : 01769 // * the 128 bytes of File Preamble (often padded with zeroes), 01770 // * the 4 bytes of "DICM" string, 01771 // * the 4 bytes of the first tag (0002, 0000),or (0002, 0001) 01772 // i.e. a total of 136 bytes. 01773 entCur = deb + 136; 01774 01775 // group 0x0002 *is always* Explicit VR Sometimes , 01776 // even if elem 0002,0010 (Transfer Syntax) tells us the file is 01777 // *Implicit* VR (see former 'gdcmData/icone.dcm') 01778 01779 if( memcmp(entCur, "UL", (size_t)2) == 0 || 01780 memcmp(entCur, "OB", (size_t)2) == 0 || 01781 memcmp(entCur, "UI", (size_t)2) == 0 || 01782 memcmp(entCur, "CS", (size_t)2) == 0 ) // CS, to remove later 01783 // when Write DCM *adds* 01784 // FIXME 01785 // Use Document::dicom_vr to test all the possibilities 01786 // instead of just checking for UL, OB and UI !? group 0000 01787 { 01788 Filetype = ExplicitVR; 01789 gdcmWarningMacro( "Group 0002 : Explicit Value Representation"); 01790 } 01791 else 01792 { 01793 Filetype = ImplicitVR; 01794 gdcmWarningMacro( "Group 0002 :Not an explicit Value Representation;" 01795 << "Looks like a bugged Header!"); 01796 } 01797 01798 if ( net2host ) 01799 { 01800 SwapCode = 4321; 01801 gdcmWarningMacro( "HostByteOrder != NetworkByteOrder"); 01802 } 01803 else 01804 { 01805 SwapCode = 1234; 01806 gdcmWarningMacro( "HostByteOrder = NetworkByteOrder"); 01807 } 01808 01809 // Position the file position indicator at first tag 01810 // (i.e. after the file preamble and the "DICM" string). 01811 Fp->seekg(0, std::ios::beg); 01812 Fp->seekg ( 132L, std::ios::beg); 01813 return true; 01814 } // End of DicomV3 01815 01816 // Alas, this is not a DicomV3 file and whatever happens there is no file 01817 // preamble. We can reset the file position indicator to where the data 01818 // is (i.e. the beginning of the file). 01819 gdcmWarningMacro( "Not a DICOM Version3 file"); 01820 Fp->seekg(0, std::ios::beg); 01821 01822 // Our next best chance would be to be considering a 'clean' ACR/NEMA file. 01823 // By clean we mean that the length of the first tag is written down. 01824 // If this is the case and since the length of the first group HAS to be 01825 // four (bytes), then determining the proper swap code is straightforward. 01826 01827 entCur = deb + 4; 01828 // We assume the array of char we are considering contains the binary 01829 // representation of a 32 bits integer. Hence the following dirty 01830 // trick : 01831 s32 = *((uint32_t *)(entCur)); 01832 01833 switch( s32 ) 01834 { 01835 case 0x00040000 : 01836 SwapCode = 3412; 01837 Filetype = ACR; 01838 return true; 01839 case 0x04000000 : 01840 SwapCode = 4321; 01841 Filetype = ACR; 01842 return true; 01843 case 0x00000400 : 01844 SwapCode = 2143; 01845 Filetype = ACR; 01846 return true; 01847 case 0x00000004 : 01848 SwapCode = 1234; 01849 Filetype = ACR; 01850 return true; 01851 default : 01852 // We are out of luck. It is not a DicomV3 nor a 'clean' ACR/NEMA file. 01853 // It is time for despaired wild guesses. 01854 // So, let's check if this file wouldn't happen to be 'dirty' ACR/NEMA, 01855 // i.e. the 'group length' element is not present : 01856 01857 // check the supposed-to-be 'group number' 01858 // in ( 0x0001 .. 0x0008 ) 01859 // to determine ' SwapCode' value . 01860 // Only 0 or 4321 will be possible 01861 // (no oportunity to check for the formerly well known 01862 // ACR-NEMA 'Bad Big Endian' or 'Bad Little Endian' 01863 // if unsuccessfull (i.e. neither 0x0002 nor 0x0200 etc -3, 4, ..., 8-) 01864 // the file IS NOT ACR-NEMA nor DICOM V3 01865 // Find a trick to tell it the caller... 01866 01867 s16 = *((uint16_t *)(deb)); 01868 01869 switch ( s16 ) 01870 { 01871 case 0x0001 : 01872 case 0x0002 : 01873 case 0x0003 : 01874 case 0x0004 : 01875 case 0x0005 : 01876 case 0x0006 : 01877 case 0x0007 : 01878 case 0x0008 : 01879 SwapCode = 1234; 01880 Filetype = ACR; 01881 return true; 01882 case 0x0100 : 01883 case 0x0200 : 01884 case 0x0300 : 01885 case 0x0400 : 01886 case 0x0500 : 01887 case 0x0600 : 01888 case 0x0700 : 01889 case 0x0800 : 01890 SwapCode = 4321; 01891 Filetype = ACR; 01892 return true; 01893 default : 01894 gdcmWarningMacro( "ACR/NEMA unfound swap info (Really hopeless !)"); 01895 Filetype = Unknown; 01896 return false; 01897 } 01898 } 01899 } |
|
delete all entries in the ElementSet
Implements gdcm::DocEntrySet. Definition at line 125 of file gdcmElementSet.cxx. References gdcm::ElementSet::TagHT. Referenced by gdcm::DicomDir::CreateDicomDir(), gdcm::DicomDir::SetElements(), and gdcm::ElementSet::~ElementSet().
00126 { 00127 for(TagDocEntryHT::iterator cc = TagHT.begin();cc != TagHT.end(); ++cc) 00128 { 00129 if ( cc->second ) 00130 { 00131 delete cc->second; 00132 } 00133 } 00134 TagHT.clear(); 00135 } |
|
closes the file
Definition at line 464 of file gdcmDocument.cxx. References Fp. Referenced by Document(), gdcm::File::File(), gdcm::FileHelper::GetRaw(), LoadEntryBinArea(), and OpenFile().
|
|
Re-computes the length of a ACR-NEMA/Dicom group from a DcmHeader.
Definition at line 717 of file gdcmDocument.cxx. References gdcm::ExplicitVR, gdcm::DocEntry::GetElement(), gdcm::ElementSet::GetFirstEntry(), gdcm::DocEntry::GetGroup(), gdcm::DocEntry::GetLength(), gdcm::ElementSet::GetNextEntry(), and gdcm::DocEntry::GetVR(). Referenced by gdcm::File::Write().
00718 { 00719 uint16_t gr; 00720 std::string vr; 00721 00722 int groupLength = 0; 00723 bool found0002 = false; 00724 00725 // for each zero-level Tag in the DCM Header 00726 DocEntry *entry = GetFirstEntry(); 00727 while( entry ) 00728 { 00729 gr = entry->GetGroup(); 00730 00731 if( gr == 0x0002 ) 00732 { 00733 found0002 = true; 00734 00735 if( entry->GetElement() != 0x0000 ) 00736 { 00737 vr = entry->GetVR(); 00738 00739 if( filetype == ExplicitVR ) 00740 { 00741 if ( (vr == "OB") || (vr == "OW") || (vr == "SQ") ) 00742 { 00743 // explicit VR AND OB, OW, SQ : 4 more bytes 00744 groupLength += 4; 00745 } 00746 } 00747 groupLength += 2 + 2 + 4 + entry->GetLength(); 00748 } 00749 } 00750 else if (found0002 ) 00751 break; 00752 00753 entry = GetNextEntry(); 00754 } 00755 return groupLength; 00756 } |
|
Find the value Length of the passed Header Entry.
Definition at line 1201 of file gdcmDocument.cxx. References gdcm::ExplicitVR. Referenced by ReadNextDocEntry().
01203 { 01204 std::string vr = entry->GetVR(); 01205 uint16_t length16; 01206 01207 if ( Filetype == ExplicitVR && !entry->IsImplicitVR() ) 01208 { 01209 if ( vr == "OB" || vr == "OW" || vr == "SQ" || vr == "UN" ) 01210 { 01211 // The following reserved two bytes (see PS 3.5-2003, section 01212 // "7.1.2 Data element structure with explicit vr", p 27) must be 01213 // skipped before proceeding on reading the length on 4 bytes. 01214 Fp->seekg( 2L, std::ios::cur); 01215 uint32_t length32 = ReadInt32(); 01216 01217 if ( (vr == "OB" || vr == "OW") && length32 == 0xffffffff ) 01218 { 01219 uint32_t lengthOB; 01220 try 01221 { 01222 lengthOB = FindDocEntryLengthOBOrOW(); 01223 } 01224 catch ( FormatUnexpected ) 01225 { 01226 // Computing the length failed (this happens with broken 01227 // files like gdcm-JPEG-LossLess3a.dcm). We still have a 01228 // chance to get the pixels by deciding the element goes 01229 // until the end of the file. Hence we artificially fix the 01230 // the length and proceed. 01231 long currentPosition = Fp->tellg(); 01232 Fp->seekg(0L,std::ios::end); 01233 01234 long lengthUntilEOF = (long)(Fp->tellg())-currentPosition; 01235 Fp->seekg(currentPosition, std::ios::beg); 01236 01237 entry->SetReadLength(lengthUntilEOF); 01238 entry->SetLength(lengthUntilEOF); 01239 return; 01240 } 01241 entry->SetReadLength(lengthOB); 01242 entry->SetLength(lengthOB); 01243 return; 01244 } 01245 FixDocEntryFoundLength(entry, length32); 01246 return; 01247 } 01248 01249 // Length is encoded on 2 bytes. 01250 length16 = ReadInt16(); 01251 01252 // FIXME : This heuristic supposes that the first group following 01253 // group 0002 *has* and element 0000. 01254 // BUT ... Element 0000 is optionnal :-( 01255 01256 01257 // Fixed using : HandleOutOfGroup0002() 01258 // (first hereafter strategy ...) 01259 01260 // We can tell the current file is encoded in big endian (like 01261 // Data/US-RGB-8-epicard) when we find the "Transfer Syntax" tag 01262 // and it's value is the one of the encoding of a big endian file. 01263 // In order to deal with such big endian encoded files, we have 01264 // (at least) two strategies: 01265 // * when we load the "Transfer Syntax" tag with value of big endian 01266 // encoding, we raise the proper flags. Then we wait for the end 01267 // of the META group (0x0002) among which is "Transfer Syntax", 01268 // before switching the swap code to big endian. We have to postpone 01269 // the switching of the swap code since the META group is fully encoded 01270 // in little endian, and big endian coding only starts at the next 01271 // group. The corresponding code can be hard to analyse and adds 01272 // many additional unnecessary tests for regular tags. 01273 // * the second strategy consists in waiting for trouble, that shall 01274 // appear when we find the first group with big endian encoding. This 01275 // is easy to detect since the length of a "Group Length" tag (the 01276 // ones with zero as element number) has to be of 4 (0x0004). When we 01277 // encounter 1024 (0x0400) chances are the encoding changed and we 01278 // found a group with big endian encoding. 01279 //---> Unfortunately, element 0000 is optional. 01280 //---> This will not work when missing! 01281 // We shall use this second strategy. In order to make sure that we 01282 // can interpret the presence of an apparently big endian encoded 01283 // length of a "Group Length" without committing a big mistake, we 01284 // add an additional check: we look in the already parsed elements 01285 // for the presence of a "Transfer Syntax" whose value has to be "big 01286 // endian encoding". When this is the case, chances are we have got our 01287 // hands on a big endian encoded file: we switch the swap code to 01288 // big endian and proceed... 01289 01290 // if ( element == 0x0000 && length16 == 0x0400 ) 01291 // { 01292 // std::string ts = GetTransferSyntax(); 01293 // if ( Global::GetTS()->GetSpecialTransferSyntax(ts) 01294 // != TS::ExplicitVRBigEndian ) 01295 // { 01296 // throw FormatError( "Document::FindDocEntryLength()", 01297 // " not explicit VR." ); 01298 // return; 01299 // } 01300 // length16 = 4; 01301 // SwitchByteSwapCode(); 01302 // 01303 // // Restore the unproperly loaded values i.e. the group, the element 01304 // // and the dictionary entry depending on them. 01305 // uint16_t correctGroup = SwapShort( entry->GetGroup() ); 01306 // uint16_t correctElem = SwapShort( entry->GetElement() ); 01307 // DictEntry *newTag = GetDictEntry( correctGroup, correctElem ); 01308 // if ( !newTag ) 01309 // { 01310 // // This correct tag is not in the dictionary. Create a new one. 01311 // newTag = NewVirtualDictEntry(correctGroup, correctElem); 01312 // } 01313 // // FIXME this can create a memory leaks on the old entry that be 01314 // // left unreferenced. 01315 // entry->SetDictEntry( newTag ); 01316 // } 01317 01318 // 0xffff means that we deal with 'No Length' Sequence 01319 // or 'No Length' SQItem 01320 if ( length16 == 0xffff) 01321 { 01322 length16 = 0; 01323 } 01324 FixDocEntryFoundLength( entry, (uint32_t)length16 ); 01325 return; 01326 } 01327 else 01328 { 01329 // Either implicit VR or a non DICOM conformal (see note below) explicit 01330 // VR that ommited the VR of (at least) this element. Farts happen. 01331 // [Note: according to the part 5, PS 3.5-2001, section 7.1 p25 01332 // on Data elements "Implicit and Explicit VR Data Elements shall 01333 // not coexist in a Data Set and Data Sets nested within it".] 01334 // Length is on 4 bytes. 01335 01336 // Well ... group 0002 is always coded in 'Explicit VR Litle Endian' 01337 // even if Transfer Syntax is 'Implicit VR ...' 01338 01339 FixDocEntryFoundLength( entry, ReadInt32() ); 01340 return; 01341 } 01342 } |
|
Find the Length till the next sequence delimiter.
Definition at line 1349 of file gdcmDocument.cxx. References gdcmWarningMacro.
01351 { 01352 // See PS 3.5-2001, section A.4 p. 49 on encapsulation of encoded pixel data. 01353 long positionOnEntry = Fp->tellg(); 01354 bool foundSequenceDelimiter = false; 01355 uint32_t totalLength = 0; 01356 01357 while ( !foundSequenceDelimiter ) 01358 { 01359 uint16_t group; 01360 uint16_t elem; 01361 try 01362 { 01363 group = ReadInt16(); 01364 elem = ReadInt16(); 01365 } 01366 catch ( FormatError ) 01367 { 01368 throw FormatError("Unexpected end of file encountered during ", 01369 "Document::FindDocEntryLengthOBOrOW()"); 01370 } 01371 // We have to decount the group and element we just read 01372 totalLength += 4; 01373 if ( group != 0xfffe || ( ( elem != 0xe0dd ) && ( elem != 0xe000 ) ) ) 01374 { 01375 long filePosition = Fp->tellg(); 01376 gdcmWarningMacro( "Neither an Item tag nor a Sequence delimiter tag on :" 01377 << std::hex << group << " , " << elem 01378 << ") -before- position x(" << filePosition << ")" ); 01379 01380 Fp->seekg(positionOnEntry, std::ios::beg); 01381 throw FormatUnexpected( "Neither an Item tag nor a Sequence delimiter tag."); 01382 } 01383 if ( elem == 0xe0dd ) 01384 { 01385 foundSequenceDelimiter = true; 01386 } 01387 uint32_t itemLength = ReadInt32(); 01388 // We add 4 bytes since we just read the ItemLength with ReadInt32 01389 totalLength += itemLength + 4; 01390 SkipBytes(itemLength); 01391 01392 if ( foundSequenceDelimiter ) 01393 { 01394 break; 01395 } 01396 } 01397 Fp->seekg( positionOnEntry, std::ios::beg); 01398 return totalLength; 01399 } |
|
Find the Value Representation of the current Dicom Element.
Definition at line 1405 of file gdcmDocument.cxx. References CheckDocEntryVR(), gdcm::ExplicitVR, Filetype, Fp, and gdcm::GDCM_UNKNOWN. Referenced by ReadNextDocEntry().
01406 { 01407 if ( Filetype != ExplicitVR ) 01408 return GDCM_UNKNOWN; 01409 01410 long positionOnEntry = Fp->tellg(); 01411 // Warning: we believe this is explicit VR (Value Representation) because 01412 // we used a heuristic that found "UL" in the first tag. Alas this 01413 // doesn't guarantee that all the tags will be in explicit VR. In some 01414 // cases (see e-film filtered files) one finds implicit VR tags mixed 01415 // within an explicit VR file. Hence we make sure the present tag 01416 // is in explicit VR and try to fix things if it happens not to be 01417 // the case. 01418 01419 char vr[3]; 01420 Fp->read (vr, (size_t)2); 01421 vr[2] = 0; 01422 01423 if( !CheckDocEntryVR(vr) ) 01424 { 01425 Fp->seekg(positionOnEntry, std::ios::beg); 01426 return GDCM_UNKNOWN; 01427 } 01428 return vr; 01429 } |
|
When the length of an element value is obviously wrong (because the parser went Jabberwocky) one can hope improving things by applying some heuristics.
Definition at line 1606 of file gdcmDocument.cxx. References gdcmWarningMacro, gdcm::DocEntry::GetElement(), gdcm::DocEntry::GetGroup(), gdcm::DocEntry::GetVR(), gdcm::DocEntry::SetLength(), and gdcm::DocEntry::SetReadLength().
01608 { 01609 entry->SetReadLength( foundLength ); // will be updated only if a bug is found 01610 if ( foundLength == 0xffffffff) 01611 { 01612 foundLength = 0; 01613 } 01614 01615 uint16_t gr = entry->GetGroup(); 01616 uint16_t elem = entry->GetElement(); 01617 01618 if ( foundLength % 2) 01619 { 01620 gdcmWarningMacro( "Warning : Tag with uneven length " << foundLength 01621 << " in x(" << std::hex << gr << "," << elem <<")"); 01622 } 01623 01625 // Allthough not recent many such GE corrupted images are still present 01626 // on Creatis hard disks. Hence this fix shall remain when such images 01627 // are no longer in use (we are talking a few years, here)... 01628 // Note: XMedCom probably uses such a trick since it is able to read 01629 // those pesky GE images ... 01630 if ( foundLength == 13) 01631 { 01632 // Only happens for this length ! 01633 if ( gr != 0x0008 || ( elem != 0x0070 && elem != 0x0080 ) ) 01634 { 01635 foundLength = 10; 01636 entry->SetReadLength(10); 01637 } 01638 } 01639 01641 // Occurence of such images is quite low (unless one leaves close to a 01642 // 'Leonardo' source. Hence, one might consider commenting out the 01643 // following fix on efficiency reasons. 01644 else if ( gr == 0x0009 && ( elem == 0x1113 || elem == 0x1114 ) ) 01645 { 01646 foundLength = 4; 01647 entry->SetReadLength(4); 01648 } 01649 01650 else if ( entry->GetVR() == "SQ" ) 01651 { 01652 foundLength = 0; // ReadLength is unchanged 01653 } 01654 01656 // "fffe|xxxx" which is just a marker. Delimiters length should not be 01657 // taken into account. 01658 else if( gr == 0xfffe ) 01659 { 01660 // According to the norm, fffe|0000 shouldn't exist. BUT the Philips 01661 // image gdcmData/gdcm-MR-PHILIPS-16-Multi-Seq.dcm happens to 01662 // causes extra troubles... 01663 if( entry->GetElement() != 0x0000 ) 01664 { 01665 foundLength = 0; 01666 } 01667 } 01668 entry->SetLength(foundLength); 01669 } |
|
Same as Document::GetDocEntry except it only returns a result when the corresponding entry is of type BinEntry.
Definition at line 127 of file gdcmDocEntrySet.cxx. References gdcmWarningMacro, and gdcm::DocEntrySet::GetDocEntry(). Referenced by gdcm::DocEntrySet::GetEntryBinArea(), and gdcm::DocEntrySet::SetBinEntry().
00128 { 00129 DocEntry *currentEntry = GetDocEntry(group, elem); 00130 if ( !currentEntry ) 00131 { 00132 gdcmWarningMacro( "No corresponding BinEntry " << std::hex << group << 00133 "," << elem); 00134 return NULL; 00135 } 00136 00137 return dynamic_cast<BinEntry*>(currentEntry); 00138 } |
|
Searches [both] the public [and the shadow dictionary (when they exist)] for the presence of the DictEntry with given group and element, and create a new virtual DictEntry if necessary.
Definition at line 558 of file gdcmDocEntrySet.cxx. References gdcm::GDCM_UNKNOWN, gdcm::DocEntrySet::GetDictEntry(), gdcm::DictEntry::GetName(), gdcm::DictEntry::GetVR(), gdcm::DocEntrySet::NewVirtualDictEntry(), and gdcm::TagName.
00560 { 00561 DictEntry *dictEntry = GetDictEntry(group,elem); 00562 DictEntry *goodEntry = dictEntry; 00563 std::string goodVR = vr; 00564 00565 if (elem == 0x0000) goodVR="UL"; 00566 00567 if ( goodEntry ) 00568 { 00569 if ( goodVR != goodEntry->GetVR() 00570 && goodVR != GDCM_UNKNOWN ) 00571 { 00572 goodEntry = NULL; 00573 } 00574 } 00575 00576 // Create a new virtual DictEntry if necessary 00577 if (!goodEntry) 00578 { 00579 if (dictEntry) 00580 { 00581 goodEntry = NewVirtualDictEntry(group, elem, goodVR, "FIXME", 00582 dictEntry->GetName() ); 00583 } 00584 else 00585 { 00586 goodEntry = NewVirtualDictEntry(group, elem, goodVR); 00587 } 00588 } 00589 return goodEntry; 00590 } |
|
Searches [both] the public [and the shadow dictionary (when they exist)] for the presence of the DictEntry with given group and element. The public dictionary has precedence on the shadow one.
Definition at line 534 of file gdcmDocEntrySet.cxx. References gdcmWarningMacro, and gdcm::Dict::GetEntry(). Referenced by gdcm::DocEntrySet::GetDictEntry(), gdcm::DocEntrySet::NewBinEntry(), gdcm::DocEntrySet::NewSeqEntry(), gdcm::DocEntrySet::NewValEntry(), and ReadNextDocEntry().
00535 { 00536 DictEntry *found = 0; 00537 Dict *pubDict = Global::GetDicts()->GetDefaultPubDict(); 00538 if (!pubDict) 00539 { 00540 gdcmWarningMacro( "We SHOULD have a default dictionary"); 00541 } 00542 else 00543 { 00544 found = pubDict->GetEntry(group, elem); 00545 } 00546 return found; 00547 } |
|
|
Get the reverse transformed value of the header entry. The VR value is used to define the reverse transformation to operate on the value.
Definition at line 1529 of file gdcmDocument.cxx. References gdcm::DocEntry::GetVR(), IsDocEntryAnInteger(), and gdcm::DocEntry::IsImplicitVR().
01530 { 01531 if ( IsDocEntryAnInteger(entry) && entry->IsImplicitVR() ) 01532 { 01533 std::string vr = entry->GetVR(); 01534 std::vector<std::string> tokens; 01535 std::ostringstream s; 01536 01537 if ( vr == "US" || vr == "SS" ) 01538 { 01539 uint16_t newInt16; 01540 01541 tokens.erase( tokens.begin(), tokens.end()); // clean any previous value 01542 Util::Tokenize (((ValEntry *)entry)->GetValue(), tokens, "\\"); 01543 for (unsigned int i=0; i<tokens.size(); i++) 01544 { 01545 newInt16 = atoi(tokens[i].c_str()); 01546 s << ( newInt16 & 0xFF ) 01547 << (( newInt16 >> 8 ) & 0xFF ); 01548 } 01549 tokens.clear(); 01550 } 01551 if ( vr == "UL" || vr == "SL") 01552 { 01553 uint32_t newInt32; 01554 01555 tokens.erase(tokens.begin(),tokens.end()); // clean any previous value 01556 Util::Tokenize (((ValEntry *)entry)->GetValue(), tokens, "\\"); 01557 for (unsigned int i=0; i<tokens.size();i++) 01558 { 01559 newInt32 = atoi(tokens[i].c_str()); 01560 s << (char)( newInt32 & 0xFF ) 01561 << (char)(( newInt32 >> 8 ) & 0xFF ) 01562 << (char)(( newInt32 >> 16 ) & 0xFF ) 01563 << (char)(( newInt32 >> 24 ) & 0xFF ); 01564 } 01565 tokens.clear(); 01566 } 01567 01568 #ifdef GDCM_NO_ANSI_STRING_STREAM 01569 s << std::ends; // to avoid oddities on Solaris 01570 #endif //GDCM_NO_ANSI_STRING_STREAM 01571 return s.str(); 01572 } 01573 01574 return ((ValEntry *)entry)->GetValue(); 01575 } |
|
Get the transformed value of the header entry. The VR value is used to define the transformation to operate on the value.
Definition at line 1454 of file gdcmDocument.cxx. References gdcm::DocEntry::GetLength(), gdcm::DocEntry::GetVR(), IsDocEntryAnInteger(), gdcm::DocEntry::IsImplicitVR(), SwapLong(), and SwapShort().
01455 { 01456 if ( IsDocEntryAnInteger(entry) && entry->IsImplicitVR() ) 01457 { 01458 std::string val = ((ValEntry *)entry)->GetValue(); 01459 std::string vr = entry->GetVR(); 01460 uint32_t length = entry->GetLength(); 01461 std::ostringstream s; 01462 int nbInt; 01463 01464 // When short integer(s) are expected, read and convert the following 01465 // n * 2 bytes properly i.e. as a multivaluated strings 01466 // (each single value is separated fromthe next one by '\' 01467 // as usual for standard multivaluated filels 01468 // Elements with Value Multiplicity > 1 01469 // contain a set of short integers (not a single one) 01470 01471 if( vr == "US" || vr == "SS" ) 01472 { 01473 uint16_t newInt16; 01474 01475 nbInt = length / 2; 01476 for (int i=0; i < nbInt; i++) 01477 { 01478 if( i != 0 ) 01479 { 01480 s << '\\'; 01481 } 01482 newInt16 = ( val[2*i+0] & 0xFF ) + ( ( val[2*i+1] & 0xFF ) << 8); 01483 newInt16 = SwapShort( newInt16 ); 01484 s << newInt16; 01485 } 01486 } 01487 01488 // When integer(s) are expected, read and convert the following 01489 // n * 4 bytes properly i.e. as a multivaluated strings 01490 // (each single value is separated fromthe next one by '\' 01491 // as usual for standard multivaluated filels 01492 // Elements with Value Multiplicity > 1 01493 // contain a set of integers (not a single one) 01494 else if( vr == "UL" || vr == "SL" ) 01495 { 01496 uint32_t newInt32; 01497 01498 nbInt = length / 4; 01499 for (int i=0; i < nbInt; i++) 01500 { 01501 if( i != 0) 01502 { 01503 s << '\\'; 01504 } 01505 newInt32 = ( val[4*i+0] & 0xFF ) 01506 + (( val[4*i+1] & 0xFF ) << 8 ) 01507 + (( val[4*i+2] & 0xFF ) << 16 ) 01508 + (( val[4*i+3] & 0xFF ) << 24 ); 01509 newInt32 = SwapLong( newInt32 ); 01510 s << newInt32; 01511 } 01512 } 01513 #ifdef GDCM_NO_ANSI_STRING_STREAM 01514 s << std::ends; // to avoid oddities on Solaris 01515 #endif //GDCM_NO_ANSI_STRING_STREAM 01516 return s.str(); 01517 } 01518 return ((ValEntry *)entry)->GetValue(); 01519 } |
|
Gets (from Header) a 'non string' element value.
Definition at line 57 of file gdcmDocEntrySet.cxx. References gdcm::BinEntry::GetBinArea(), and gdcm::DocEntrySet::GetBinEntry(). Referenced by gdcm::PixelReadConvert::GrabInformationsFromFile().
00058 { 00059 BinEntry *entry = GetBinEntry(group, elem); 00060 if( entry ) 00061 return entry->GetBinArea(); 00062 return 0; 00063 } |
|
Searches within Header Entries (Dicom Elements) parsed with the public and private dictionaries for the value length of a given tag..
Definition at line 73 of file gdcmDocEntrySet.cxx. References gdcm::DocEntrySet::GetDocEntry(), and gdcm::DocEntry::GetLength(). Referenced by gdcm::DicomDir::SetElement(), and gdcm::File::Write().
00074 { 00075 DocEntry *entry = GetDocEntry(group, elem); 00076 if( entry ) 00077 return entry->GetLength(); 00078 return -1; 00079 } |
|
Get the "std::string representable" value of the Dicom entry.
Definition at line 43 of file gdcmDocEntrySet.cxx. References gdcm::GDCM_UNFOUND, gdcm::DocEntrySet::GetDocEntry(), and gdcm::ContentEntry::GetValue(). Referenced by gdcm::SerieHelper::AddFileName(), gdcm::File::AnonymizeFile(), Document(), gdcm::File::File(), gdcm::File::GetBitsAllocated(), gdcm::File::GetBitsStored(), gdcm::File::GetHighBitPosition(), gdcm::File::GetImageNumber(), gdcm::File::GetImageOrientationPatient(), gdcm::File::GetLUTNbits(), gdcm::File::GetModality(), gdcm::File::GetNumberOfScalarComponents(), gdcm::File::GetPixelType(), gdcm::File::GetPlanarConfiguration(), gdcm::File::GetRescaleIntercept(), gdcm::File::GetRescaleSlope(), gdcm::File::GetSamplesPerPixel(), GetTransferSyntaxName(), gdcm::File::GetXOrigin(), gdcm::File::GetXSize(), gdcm::File::GetXSpacing(), gdcm::File::GetYOrigin(), gdcm::File::GetYSize(), gdcm::File::GetYSpacing(), gdcm::File::GetZOrigin(), gdcm::File::GetZSize(), gdcm::File::GetZSpacing(), gdcm::PixelReadConvert::GrabInformationsFromFile(), gdcm::File::IsMonochrome(), gdcm::File::IsPaletteColor(), gdcm::File::IsReadable(), gdcm::File::IsSignedPixelData(), gdcm::File::IsYBRFull(), operator<(), gdcm::DicomDir::SetElement(), and gdcm::File::Write().
00044 { 00045 ContentEntry *entry = dynamic_cast<ContentEntry *>(GetDocEntry(group,elem)); 00046 if( entry ) 00047 return entry->GetValue(); 00048 return GDCM_UNFOUND; 00049 } |
|
Searches within Header Entries (Dicom Elements) parsed with the public [and private dictionaries] for the element value representation of a given tag.. Obtaining the VR (Value Representation) might be needed by caller to convert the string typed content to caller's native type (think of C++ vs Python). The VR is actually of a higher level of semantics than just the native C++ type.
Definition at line 94 of file gdcmDocEntrySet.cxx. References gdcm::GDCM_UNFOUND, gdcm::DocEntrySet::GetDocEntry(), and gdcm::DocEntry::GetVR().
00095 { 00096 DocEntry *entry = GetDocEntry(group, elem); 00097 if( entry ) 00098 return entry->GetVR(); 00099 return GDCM_UNFOUND; 00100 } |
|
Accessor to Filename.
Definition at line 79 of file gdcmDocument.h. Referenced by gdcm::SerieHelper::FileNameLessThan(), gdcm::DicomDir::ParseDirectory(), and gdcm::DicomDir::SetElement().
00079 { return Filename; } |
|
returns the File Type (ACR, ACR_LIBIDO, ExplicitVR, ImplicitVR, Unknown)
Definition at line 276 of file gdcmDocument.cxx. References Filetype, and gdcm::FileType.
00277 { 00278 return Filetype; 00279 } |
|
Get the first entry while visiting *the* 'zero level' DocEntrySet (DocEntries out of any Sequence).
Implements gdcm::DocEntrySet. Definition at line 142 of file gdcmElementSet.cxx. References gdcm::ElementSet::ItTagHT, and gdcm::ElementSet::TagHT. Referenced by ComputeGroup0002Length(), gdcm::DicomDir::DicomDir(), and gdcm::DicomDir::NewMeta().
00143 { 00144 ItTagHT = TagHT.begin(); 00145 if (ItTagHT != TagHT.end()) 00146 return ItTagHT->second; 00147 return NULL; 00148 } |
|
Get the next entry while visiting *the* 'zero level' DocEntrySet (DocEntries out of any Sequence).
Implements gdcm::DocEntrySet. Definition at line 156 of file gdcmElementSet.cxx. References gdcmAssertMacro, gdcm::ElementSet::ItTagHT, and gdcm::ElementSet::TagHT. Referenced by ComputeGroup0002Length().
00157 { 00158 gdcmAssertMacro (ItTagHT != TagHT.end()); 00159 00160 ++ItTagHT; 00161 if (ItTagHT != TagHT.end()) 00162 return ItTagHT->second; 00163 return NULL; 00164 } |
|
Gets the print level for the Dicom Entries.
Definition at line 48 of file gdcmBase.h.
00048 { return PrintLevel; }; |
|
Get the public dictionary used.
Definition at line 183 of file gdcmDocument.cxx. References RefPubDict. Referenced by gdcm::DicomDir::SetElement().
00184 { 00185 return RefPubDict; 00186 } |
|
Same as Document::GetDocEntry except it only returns a result when the corresponding entry is of type SeqEntry.
Definition at line 148 of file gdcmDocEntrySet.cxx. References gdcmWarningMacro, and gdcm::DocEntrySet::GetDocEntry().
00149 { 00150 DocEntry *currentEntry = GetDocEntry(group, elem); 00151 if ( !currentEntry ) 00152 { 00153 gdcmWarningMacro( "No corresponding SeqEntry " << std::hex << group << 00154 "," << elem); 00155 return NULL; 00156 } 00157 00158 return dynamic_cast<SeqEntry*>(currentEntry); 00159 } |
|
Get the shadow dictionary used.
Definition at line 191 of file gdcmDocument.cxx. References RefShaDict.
00192 { 00193 return RefShaDict; 00194 } |
|
'Swap code' accessor (see SwapCode )
Definition at line 66 of file gdcmDocument.h. Referenced by gdcm::PixelReadConvert::GrabInformationsFromFile().
00066 { return SwapCode; } |
|
Accessor to the Transfer Syntax (when present) of the current document (it internally handles reading the value from disk when only parsing occured).
Definition at line 287 of file gdcmDocument.cxx. References gdcm::GDCM_UNKNOWN, gdcm::ElementSet::GetDocEntry(), gdcm::ContentEntry::GetValue(), and LoadDocEntrySafe(). Referenced by gdcm::File::ComputeJPEGFragmentInfo(), gdcm::File::ComputeRLEInfo(), gdcm::File::File(), gdcm::PixelReadConvert::GrabInformationsFromFile(), and HandleOutOfGroup0002().
00288 { 00289 DocEntry *entry = GetDocEntry(0x0002, 0x0010); 00290 if ( !entry ) 00291 { 00292 return GDCM_UNKNOWN; 00293 } 00294 00295 // The entry might be present but not loaded (parsing and loading 00296 // happen at different stages): try loading and proceed with check... 00297 LoadDocEntrySafe(entry); 00298 if (ValEntry *valEntry = dynamic_cast< ValEntry* >(entry) ) 00299 { 00300 std::string transfer = valEntry->GetValue(); 00301 // The actual transfer (as read from disk) might be padded. We 00302 // first need to remove the potential padding. We can make the 00303 // weak assumption that padding was not executed with digits... 00304 if ( transfer.length() == 0 ) 00305 { 00306 // for brain damaged headers 00307 return GDCM_UNKNOWN; 00308 } 00309 while ( !isdigit((unsigned char)transfer[transfer.length()-1]) ) 00310 { 00311 transfer.erase(transfer.length()-1, 1); 00312 } 00313 return transfer; 00314 } 00315 return GDCM_UNKNOWN; 00316 } |
|
Accesses the info from 0002,0010 : Transfer Syntax and TS.
Definition at line 322 of file gdcmDocument.cxx. References gdcm::GDCM_NOTLOADED, gdcm::GDCM_UNFOUND, gdcmErrorMacro, gdcmWarningMacro, gdcm::DocEntrySet::GetEntryValue(), and gdcm::TSKey. Referenced by HandleOutOfGroup0002().
00323 { 00324 // use the TS (TS : Transfer Syntax) 00325 std::string transferSyntax = GetEntryValue(0x0002,0x0010); 00326 00327 if ( (transferSyntax.find(GDCM_NOTLOADED) < transferSyntax.length()) ) 00328 { 00329 gdcmErrorMacro( "Transfer Syntax not loaded. " << std::endl 00330 << "Better you increase MAX_SIZE_LOAD_ELEMENT_VALUE" ); 00331 return "Uncompressed ACR-NEMA"; 00332 } 00333 if ( transferSyntax == GDCM_UNFOUND ) 00334 { 00335 gdcmWarningMacro( "Unfound Transfer Syntax (0002,0010)"); 00336 return "Uncompressed ACR-NEMA"; 00337 } 00338 00339 // we do it only when we need it 00340 const TSKey &tsName = Global::GetTS()->GetValue( transferSyntax ); 00341 00342 // Global::GetTS() is a global static you shall never try to delete it! 00343 return tsName; 00344 } |
|
Same as Document::GetDocEntry except it only returns a result when the corresponding entry is of type ValEntry.
Definition at line 110 of file gdcmDocEntrySet.cxx. References gdcm::DocEntrySet::GetDocEntry(). Referenced by gdcm::DocEntrySet::SetValEntry(), and gdcm::File::Write().
00111 { 00112 DocEntry *currentEntry = GetDocEntry(group, elem); 00113 if ( !currentEntry ) 00114 return NULL; 00115 00116 return dynamic_cast<ValEntry*>(currentEntry); 00117 } |
|
Handle broken private tag from Philips NTSCAN where the endianess is being switch to BigEndian for no apparent reason.
Definition at line 2052 of file gdcmDocument.cxx. References SwitchByteSwapCode(). Referenced by ReadNextDocEntry().
02053 { 02054 // Endian reversion. Some files contain groups of tags with reversed endianess. 02055 static int reversedEndian = 0; 02056 // try to fix endian switching in the middle of headers 02057 if ((group == 0xfeff) && (elem == 0x00e0)) 02058 { 02059 // start endian swap mark for group found 02060 reversedEndian++; 02061 SwitchByteSwapCode(); 02062 // fix the tag 02063 group = 0xfffe; 02064 elem = 0xe000; 02065 } 02066 else if (group == 0xfffe && elem == 0xe00d && reversedEndian) 02067 { 02068 // end of reversed endian group 02069 reversedEndian--; 02070 SwitchByteSwapCode(); 02071 } 02072 } |
|
Group 0002 is always coded Little Endian whatever Transfer Syntax is.
Definition at line 2079 of file gdcmDocument.cxx. References Filetype, gdcmWarningMacro, GetTransferSyntax(), GetTransferSyntaxName(), Group0002Parsed, gdcm::ImplicitVR, SwapShort(), and SwitchByteSwapCode(). Referenced by ReadNextDocEntry().
02080 { 02081 // Endian reversion. Some files contain groups of tags with reversed endianess. 02082 if ( !Group0002Parsed && group != 0x0002) 02083 { 02084 Group0002Parsed = true; 02085 // we just came out of group 0002 02086 // if Transfer syntax is Big Endian we have to change CheckSwap 02087 02088 std::string ts = GetTransferSyntax(); 02089 if ( !Global::GetTS()->IsTransferSyntax(ts) ) 02090 { 02091 gdcmWarningMacro("True DICOM File, with NO Tansfer Syntax: " << ts ); 02092 return; 02093 } 02094 02095 // Group 0002 is always 'Explicit ...' enven when Transfer Syntax says 'Implicit ..." 02096 02097 if ( Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ImplicitVRLittleEndian ) 02098 { 02099 Filetype = ImplicitVR; 02100 } 02101 02102 // FIXME Strangely, this works with 02103 //'Implicit VR Transfer Syntax (GE Private) 02104 if ( Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ExplicitVRBigEndian ) 02105 { 02106 gdcmWarningMacro("Transfer Syntax Name = [" 02107 << GetTransferSyntaxName() << "]" ); 02108 SwitchByteSwapCode(); 02109 group = SwapShort(group); 02110 elem = SwapShort(elem); 02111 } 02112 } 02113 } |
|
Loads all the needed Dictionaries.
Reimplemented in gdcm::DicomDir. Definition at line 764 of file gdcmDocument.cxx. References Filetype, RefPubDict, RefShaDict, and gdcm::Unknown. Referenced by Document().
00765 { 00766 RefPubDict = Global::GetDicts()->GetDefaultPubDict(); 00767 RefShaDict = NULL; 00768 Filetype = Unknown; 00769 } |
|
Modifies the value of a given Header Entry (Dicom Element) when it exists. Create it with the given value when unexistant. A copy of the binArea is made to be kept in the Document.
Definition at line 309 of file gdcmDocEntrySet.cxx. References gdcm::DocEntrySet::AddEntry(), gdcmWarningMacro, gdcm::DocEntrySet::GetDocEntry(), gdcm::DocEntry::GetVR(), gdcm::DocEntrySet::NewBinEntry(), gdcm::DocEntrySet::RemoveEntry(), gdcm::DocEntrySet::SetBinEntry(), and gdcm::TagName. Referenced by gdcm::File::InitializeDefaultFile(), and gdcm::FileHelper::InsertBinEntry().
00312 { 00313 BinEntry *binEntry = 0; 00314 DocEntry *currentEntry = GetDocEntry( group, elem ); 00315 00316 // Verify the currentEntry 00317 if (currentEntry) 00318 { 00319 binEntry = dynamic_cast<BinEntry *>(currentEntry); 00320 00321 // Verify the VR 00322 if( binEntry ) 00323 if( binEntry->GetVR()!=vr ) 00324 binEntry = NULL; 00325 00326 // if currentEntry doesn't correspond to the requested valEntry 00327 if( !binEntry) 00328 { 00329 if( !RemoveEntry(currentEntry) ) 00330 { 00331 gdcmWarningMacro( "Removal of previous DocEntry failed."); 00332 00333 return NULL; 00334 } 00335 } 00336 } 00337 00338 // Create a new binEntry if necessary 00339 if( !binEntry) 00340 { 00341 binEntry = NewBinEntry(group, elem, vr); 00342 00343 if ( !AddEntry(binEntry) ) 00344 { 00345 gdcmWarningMacro( "AddEntry failed allthough this is a creation."); 00346 00347 delete binEntry; 00348 return NULL; 00349 } 00350 } 00351 00352 // Set the binEntry value 00353 uint8_t *tmpArea; 00354 if( lgth>0 && binArea ) 00355 { 00356 tmpArea = new uint8_t[lgth]; 00357 memcpy(tmpArea,binArea,lgth); 00358 } 00359 else 00360 { 00361 tmpArea = 0; 00362 } 00363 if( !SetBinEntry(tmpArea,lgth,binEntry) ) 00364 { 00365 if( tmpArea ) 00366 { 00367 delete[] tmpArea; 00368 } 00369 } 00370 00371 return binEntry; 00372 } |
|
Modifies the value of a given Doc Entry (Dicom Element) when it exists. Creates it when unexistant.
Definition at line 382 of file gdcmDocEntrySet.cxx. References gdcm::DocEntrySet::AddEntry(), gdcmWarningMacro, gdcm::DocEntrySet::GetDocEntry(), gdcm::DocEntrySet::NewSeqEntry(), and gdcm::DocEntrySet::RemoveEntry(). Referenced by gdcm::FileHelper::InsertSeqEntry().
00383 { 00384 SeqEntry *seqEntry = 0; 00385 DocEntry *currentEntry = GetDocEntry( group, elem ); 00386 00387 // Verify the currentEntry 00388 if( currentEntry ) 00389 { 00390 seqEntry = dynamic_cast<SeqEntry *>(currentEntry); 00391 00392 // Verify the VR 00393 if( seqEntry ) 00394 seqEntry = NULL; 00395 00396 // if currentEntry doesn't correspond to the requested seqEntry 00397 if( !seqEntry ) 00398 { 00399 if (!RemoveEntry(currentEntry)) 00400 { 00401 gdcmWarningMacro( "Removal of previous DocEntry failed."); 00402 00403 return NULL; 00404 } 00405 } 00406 } 00407 // Create a new seqEntry if necessary 00408 if( !seqEntry ) 00409 { 00410 seqEntry = NewSeqEntry(group, elem); 00411 00412 if( !AddEntry(seqEntry) ) 00413 { 00414 gdcmWarningMacro( "AddEntry failed allthough this is a creation."); 00415 00416 delete seqEntry; 00417 return NULL; 00418 } 00419 } 00420 00421 // TODO : Find a trick to insert a SequenceDelimitationItem 00422 // in the SeqEntry, at the end. 00423 return seqEntry; 00424 } |
|
Modifies the value of a given Doc Entry (Dicom Element) when it exists. Create it with the given value when unexistant.
Definition at line 250 of file gdcmDocEntrySet.cxx. References gdcm::DocEntrySet::AddEntry(), gdcmWarningMacro, gdcm::DocEntrySet::GetDocEntry(), gdcm::DocEntry::GetVR(), gdcm::DocEntrySet::NewValEntry(), gdcm::DocEntrySet::RemoveEntry(), gdcm::DocEntrySet::SetValEntry(), and gdcm::TagName. Referenced by gdcm::File::InitializeDefaultFile(), gdcm::FileHelper::InsertValEntry(), and gdcm::File::Write().
00253 { 00254 ValEntry *valEntry = 0; 00255 DocEntry *currentEntry = GetDocEntry( group, elem ); 00256 00257 if (currentEntry) 00258 { 00259 valEntry = dynamic_cast<ValEntry *>(currentEntry); 00260 00261 // Verify the VR 00262 if( valEntry ) 00263 if( valEntry->GetVR()!=vr ) 00264 valEntry = NULL; 00265 00266 // if currentEntry doesn't correspond to the requested valEntry 00267 if( !valEntry) 00268 { 00269 if( !RemoveEntry(currentEntry) ) 00270 { 00271 gdcmWarningMacro( "Removal of previous DocEntry failed."); 00272 00273 return NULL; 00274 } 00275 } 00276 } 00277 00278 // Create a new valEntry if necessary 00279 if( !valEntry ) 00280 { 00281 valEntry = NewValEntry( group, elem, vr ); 00282 00283 if ( !AddEntry(valEntry) ) 00284 { 00285 gdcmWarningMacro("AddEntry failed although this is a creation."); 00286 00287 delete valEntry; 00288 return NULL; 00289 } 00290 } 00291 00292 // Set the binEntry value 00293 SetValEntry(value, valEntry); // The std::string value 00294 return valEntry; 00295 } |
|
Predicate for dicom version 3 file.
Definition at line 245 of file gdcmDocument.cxx. References gdcm::ElementSet::GetDocEntry(). Referenced by gdcm::File::GetYSize(), and gdcm::PixelReadConvert::GrabInformationsFromFile().
00246 { 00247 // Checking if Transfer Syntax exists is enough 00248 // Anyway, it's to late check if the 'Preamble' was found ... 00249 // And ... would it be a rich idea to check ? 00250 // (some 'no Preamble' DICOM images exist !) 00251 return GetDocEntry(0x0002, 0x0010) != NULL; 00252 } |
|
Apply some heuristics to predict whether the considered element value contains/represents an integer or not.
Definition at line 1677 of file gdcmDocument.cxx. References Fp, gdcmWarningMacro, gdcm::DocEntry::GetElement(), gdcm::DocEntry::GetGroup(), gdcm::DocEntry::GetLength(), and gdcm::DocEntry::GetVR(). Referenced by GetDocEntryUnvalue(), GetDocEntryValue(), and LoadDocEntry().
01678 { 01679 uint16_t elem = entry->GetElement(); 01680 uint16_t group = entry->GetGroup(); 01681 const std::string &vr = entry->GetVR(); 01682 uint32_t length = entry->GetLength(); 01683 01684 // When we have some semantics on the element we just read, and if we 01685 // a priori know we are dealing with an integer, then we shall be 01686 // able to swap it's element value properly. 01687 if ( elem == 0 ) // This is the group length of the group 01688 { 01689 if ( length == 4 ) 01690 { 01691 return true; 01692 } 01693 else 01694 { 01695 // Allthough this should never happen, still some images have a 01696 // corrupted group length [e.g. have a glance at offset x(8336) of 01697 // gdcmData/gdcm-MR-PHILIPS-16-Multi-Seq.dcm]. 01698 // Since for dicom compliant and well behaved headers, the present 01699 // test is useless (and might even look a bit paranoid), when we 01700 // encounter such an ill-formed image, we simply display a warning 01701 // message and proceed on parsing (while crossing fingers). 01702 long filePosition = Fp->tellg(); 01703 gdcmWarningMacro( "Erroneous Group Length element length on : (" 01704 << std::hex << group << " , " << elem 01705 << ") -before- position x(" << filePosition << ")" 01706 << "lgt : " << length ); 01707 } 01708 } 01709 01710 if ( vr == "UL" || vr == "US" || vr == "SL" || vr == "SS" ) 01711 { 01712 return true; 01713 } 01714 return false; 01715 } |
|
Tells us if the ElementSet contains no entry.
Implements gdcm::DocEntrySet. Definition at line 63 of file gdcmElementSet.h. Referenced by IsReadable().
00063 { return TagHT.empty(); };
|
|
Predicate for Papyrus file Dedicated to whomsoever it may concern.
Definition at line 259 of file gdcmDocument.cxx. References gdcm::ElementSet::GetDocEntry().
00260 { 00261 // check for Papyrus private Sequence 00262 DocEntry *e = GetDocEntry(0x0041, 0x1050); 00263 if ( !e ) 00264 return false; 00265 // check if it's actually a Sequence 00266 if ( !dynamic_cast<SeqEntry*>(e) ) 00267 return false; 00268 return true; 00269 } |
|
This predicate, based on hopefully reasonable heuristics, decides whether or not the current Document was properly parsed and contains the mandatory information for being considered as a well formed and usable Dicom/Acr File.
Reimplemented in gdcm::DicomDir, and gdcm::File. Definition at line 224 of file gdcmDocument.cxx. References Filetype, gdcmWarningMacro, gdcm::ElementSet::IsEmpty(), and gdcm::Unknown.
00225 { 00226 if( Filetype == Unknown) 00227 { 00228 gdcmWarningMacro( "Wrong filetype"); 00229 return false; 00230 } 00231 00232 if ( IsEmpty() ) 00233 { 00234 gdcmWarningMacro( "No tag in internal hash table."); 00235 return false; 00236 } 00237 00238 return true; 00239 } |
|
Loads the element content if its length doesn't exceed the value specified with Document::SetMaxSizeLoadEntry().
Definition at line 1030 of file gdcmDocument.cxx. References Fp, gdcm::GDCM_BINLOADED, gdcm::GDCM_NOTLOADED, gdcm::GDCM_UNREAD, gdcmErrorMacro, gdcmWarningMacro, gdcm::DocEntry::GetGroup(), gdcm::DocEntry::GetLength(), gdcm::DocEntry::GetOffset(), gdcm::DocEntry::GetVR(), IsDocEntryAnInteger(), LoadEntryBinArea(), MaxSizeLoadEntry, ReadInt16(), ReadInt32(), gdcm::ValEntry::SetValue(), and gdcm::ContentEntry::SetValue(). Referenced by LoadDocEntrySafe(), and ParseDES().
01031 { 01032 uint16_t group = entry->GetGroup(); 01033 std::string vr = entry->GetVR(); 01034 uint32_t length = entry->GetLength(); 01035 01036 Fp->seekg((long)entry->GetOffset(), std::ios::beg); 01037 01038 // A SeQuence "contains" a set of Elements. 01039 // (fffe e000) tells us an Element is beginning 01040 // (fffe e00d) tells us an Element just ended 01041 // (fffe e0dd) tells us the current SeQuence just ended 01042 if( group == 0xfffe ) 01043 { 01044 // NO more value field for SQ ! 01045 return; 01046 } 01047 01048 // When the length is zero things are easy: 01049 if ( length == 0 ) 01050 { 01051 ((ValEntry *)entry)->SetValue(""); 01052 return; 01053 } 01054 01055 // The elements whose length is bigger than the specified upper bound 01056 // are not loaded. Instead we leave a short notice of the offset of 01057 // the element content and it's length. 01058 01059 std::ostringstream s; 01060 if (length > MaxSizeLoadEntry) 01061 { 01062 if (BinEntry *binEntryPtr = dynamic_cast< BinEntry* >(entry) ) 01063 { 01064 //s << "gdcm::NotLoaded (BinEntry)"; 01065 s << GDCM_NOTLOADED; 01066 s << " Address:" << (long)entry->GetOffset(); 01067 s << " Length:" << entry->GetLength(); 01068 s << " x(" << std::hex << entry->GetLength() << ")"; 01069 binEntryPtr->SetValue(s.str()); 01070 } 01071 // Be carefull : a BinEntry IS_A ValEntry ... 01072 else if (ValEntry *valEntryPtr = dynamic_cast< ValEntry* >(entry) ) 01073 { 01074 // s << "gdcm::NotLoaded. (ValEntry)"; 01075 s << GDCM_NOTLOADED; 01076 s << " Address:" << (long)entry->GetOffset(); 01077 s << " Length:" << entry->GetLength(); 01078 s << " x(" << std::hex << entry->GetLength() << ")"; 01079 valEntryPtr->SetValue(s.str()); 01080 } 01081 else 01082 { 01083 // fusible 01084 gdcmErrorMacro( "MaxSizeLoadEntry exceeded, neither a BinEntry " 01085 << "nor a ValEntry ?! Should never print that !" ); 01086 } 01087 01088 // to be sure we are at the end of the value ... 01089 Fp->seekg((long)entry->GetOffset()+(long)entry->GetLength(), 01090 std::ios::beg); 01091 return; 01092 } 01093 01094 // When we find a BinEntry not very much can be done : 01095 if (BinEntry *binEntryPtr = dynamic_cast< BinEntry* >(entry) ) 01096 { 01097 s << GDCM_BINLOADED; 01098 binEntryPtr->SetValue(s.str()); 01099 LoadEntryBinArea(binEntryPtr); // last one, not to erase length ! 01100 return; 01101 } 01102 01104 if ( IsDocEntryAnInteger(entry) ) 01105 { 01106 uint32_t NewInt; 01107 int nbInt; 01108 // When short integer(s) are expected, read and convert the following 01109 // n *two characters properly i.e. consider them as short integers as 01110 // opposed to strings. 01111 // Elements with Value Multiplicity > 1 01112 // contain a set of integers (not a single one) 01113 if (vr == "US" || vr == "SS") 01114 { 01115 nbInt = length / 2; 01116 NewInt = ReadInt16(); 01117 s << NewInt; 01118 if (nbInt > 1) 01119 { 01120 for (int i=1; i < nbInt; i++) 01121 { 01122 s << '\\'; 01123 NewInt = ReadInt16(); 01124 s << NewInt; 01125 } 01126 } 01127 } 01128 // See above comment on multiple integers (mutatis mutandis). 01129 else if (vr == "UL" || vr == "SL") 01130 { 01131 nbInt = length / 4; 01132 NewInt = ReadInt32(); 01133 s << NewInt; 01134 if (nbInt > 1) 01135 { 01136 for (int i=1; i < nbInt; i++) 01137 { 01138 s << '\\'; 01139 NewInt = ReadInt32(); 01140 s << NewInt; 01141 } 01142 } 01143 } 01144 #ifdef GDCM_NO_ANSI_STRING_STREAM 01145 s << std::ends; // to avoid oddities on Solaris 01146 #endif //GDCM_NO_ANSI_STRING_STREAM 01147 01148 ((ValEntry *)entry)->SetValue(s.str()); 01149 return; 01150 } 01151 01152 // FIXME: We need an additional byte for storing \0 that is not on disk 01153 char *str = new char[length+1]; 01154 Fp->read(str, (size_t)length); 01155 str[length] = '\0'; //this is only useful when length is odd 01156 // Special DicomString call to properly handle \0 and even length 01157 std::string newValue; 01158 if( length % 2 ) 01159 { 01160 newValue = Util::DicomString(str, length+1); 01161 gdcmWarningMacro("Warning: bad length: " << length << 01162 ",For string :" << newValue.c_str()); 01163 // Since we change the length of string update it length 01164 //entry->SetReadLength(length+1); 01165 } 01166 else 01167 { 01168 newValue = Util::DicomString(str, length); 01169 } 01170 delete[] str; 01171 01172 if ( ValEntry *valEntry = dynamic_cast<ValEntry* >(entry) ) 01173 { 01174 if ( Fp->fail() || Fp->eof()) 01175 { 01176 gdcmWarningMacro("Unread element value"); 01177 valEntry->SetValue(GDCM_UNREAD); 01178 return; 01179 } 01180 01181 if( vr == "UI" ) 01182 { 01183 // Because of correspondance with the VR dic 01184 valEntry->SetValue(newValue); 01185 } 01186 else 01187 { 01188 valEntry->SetValue(newValue); 01189 } 01190 } 01191 else 01192 { 01193 gdcmErrorMacro( "Should have a ValEntry, here !"); 01194 } 01195 } |
|
Loads the element while preserving the current underlying file position indicator as opposed to LoadDocEntry that modifies it.
Definition at line 581 of file gdcmDocument.cxx. References Fp, and LoadDocEntry(). Referenced by GetTransferSyntax().
00582 { 00583 if(Fp) 00584 { 00585 long PositionOnEntry = Fp->tellg(); 00586 LoadDocEntry(entry); 00587 Fp->seekg(PositionOnEntry, std::ios::beg); 00588 } 00589 } |
|
Loads (from disk) the element content when a string is not suitable.
Definition at line 541 of file gdcmDocument.cxx. References CloseFile(), Fp, gdcmWarningMacro, gdcm::BinEntry::GetBinArea(), gdcm::DocEntry::GetLength(), gdcm::DocEntry::GetOffset(), OpenFile(), and gdcm::BinEntry::SetBinArea().
00542 { 00543 if(elem->GetBinArea()) 00544 return; 00545 00546 bool openFile = !Fp; 00547 if(openFile) 00548 OpenFile(); 00549 00550 size_t o =(size_t)elem->GetOffset(); 00551 Fp->seekg(o, std::ios::beg); 00552 00553 size_t l = elem->GetLength(); 00554 uint8_t *a = new uint8_t[l]; 00555 if( !a ) 00556 { 00557 gdcmWarningMacro( "Cannot allocate BinEntry content"); 00558 return; 00559 } 00560 00562 Fp->read((char*)a, l); 00563 if( Fp->fail() || Fp->eof()) 00564 { 00565 delete[] a; 00566 return; 00567 } 00568 00569 elem->SetBinArea(a); 00570 00571 if(openFile) 00572 CloseFile(); 00573 } |
|
Loads (from disk) the element content when a string is not suitable.
Definition at line 522 of file gdcmDocument.cxx. References gdcm::ElementSet::GetDocEntry(). Referenced by Document(), gdcm::PixelReadConvert::GrabInformationsFromFile(), and LoadDocEntry().
00523 { 00524 // Search the corresponding DocEntry 00525 DocEntry *docElement = GetDocEntry(group, elem); 00526 if ( !docElement ) 00527 return; 00528 00529 BinEntry *binElement = dynamic_cast<BinEntry *>(docElement); 00530 if( !binElement ) 00531 return; 00532 00533 LoadEntryBinArea(binElement); 00534 } |
|
Build a new Bin Entry from all the low level arguments. Check for existence of dictionary entry, and build a default one when absent.
Definition at line 471 of file gdcmDocEntrySet.cxx. References gdcmAssertMacro, gdcmWarningMacro, gdcm::DocEntrySet::GetDictEntry(), and gdcm::TagName. Referenced by gdcm::FileHelper::CopyBinEntry(), gdcm::DocEntrySet::InsertBinEntry(), and ReadNextDocEntry().
00473 { 00474 DictEntry *dictEntry = GetDictEntry(group, elem, vr); 00475 gdcmAssertMacro(dictEntry); 00476 00477 BinEntry *newEntry = new BinEntry(dictEntry); 00478 if (!newEntry) 00479 { 00480 gdcmWarningMacro( "Failed to allocate BinEntry"); 00481 return 0; 00482 } 00483 return newEntry; 00484 } |
|
Build a new Seq Entry from all the low level arguments. Check for existence of dictionary entry, and build a default one when absent.
Definition at line 493 of file gdcmDocEntrySet.cxx. References gdcmAssertMacro, gdcmWarningMacro, and gdcm::DocEntrySet::GetDictEntry(). Referenced by gdcm::DocEntrySet::InsertSeqEntry(), and ReadNextDocEntry().
00494 { 00495 DictEntry *dictEntry = GetDictEntry(group, elem, "SQ"); 00496 gdcmAssertMacro(dictEntry); 00497 00498 SeqEntry *newEntry = new SeqEntry( dictEntry ); 00499 if (!newEntry) 00500 { 00501 gdcmWarningMacro( "Failed to allocate SeqEntry"); 00502 return 0; 00503 } 00504 return newEntry; 00505 } |
|
Build a new Val Entry from all the low level arguments. Check for existence of dictionary entry, and build a default one when absent.
Definition at line 447 of file gdcmDocEntrySet.cxx. References gdcmAssertMacro, gdcmWarningMacro, gdcm::DocEntrySet::GetDictEntry(), and gdcm::TagName. Referenced by gdcm::FileHelper::CopyValEntry(), gdcm::DocEntrySet::InsertValEntry(), and ReadNextDocEntry().
00449 { 00450 DictEntry *dictEntry = GetDictEntry(group, elem, vr); 00451 gdcmAssertMacro(dictEntry); 00452 00453 ValEntry *newEntry = new ValEntry(dictEntry); 00454 if (!newEntry) 00455 { 00456 gdcmWarningMacro( "Failed to allocate ValEntry"); 00457 return 0; 00458 } 00459 return newEntry; 00460 } |
|
Request a new virtual dict entry to the dict set.
Definition at line 515 of file gdcmDocEntrySet.cxx. References gdcm::TagName. Referenced by gdcm::File::File(), and gdcm::DocEntrySet::GetDictEntry().
00519 {
00520 return Global::GetDicts()->NewVirtualDictEntry(group,elem,vr,vm,name);
00521 }
|
|
Tries to open the file Document::Filename and checks the preamble when existing.
Definition at line 395 of file gdcmDocument.cxx. References CloseFile(), Fp, gdcmDebugMacro, gdcmWarningMacro, and HasDCMPreamble. Referenced by Document(), gdcm::File::File(), gdcm::FileHelper::GetRaw(), and LoadEntryBinArea().
00396 { 00397 HasDCMPreamble = false; 00398 if (Filename.length() == 0) 00399 { 00400 return 0; 00401 } 00402 00403 if(Fp) 00404 { 00405 gdcmWarningMacro( "File already open: " << Filename.c_str()); 00406 CloseFile(); 00407 } 00408 00409 Fp = new std::ifstream(Filename.c_str(), std::ios::in | std::ios::binary); 00410 if( ! *Fp ) 00411 { 00412 gdcmDebugMacro( "Cannot open file: " << Filename.c_str()); 00413 delete Fp; 00414 Fp = 0; 00415 return 0; 00416 } 00417 00418 uint16_t zero = 0; 00419 Fp->read((char*)&zero, (size_t)2); 00420 if( Fp->eof() ) 00421 { 00422 CloseFile(); 00423 return 0; 00424 } 00425 00426 //ACR -- or DICOM with no Preamble; may start with a Shadow Group -- 00427 if( 00428 zero == 0x0001 || zero == 0x0100 || zero == 0x0002 || zero == 0x0200 || 00429 zero == 0x0003 || zero == 0x0300 || zero == 0x0004 || zero == 0x0400 || 00430 zero == 0x0005 || zero == 0x0500 || zero == 0x0006 || zero == 0x0600 || 00431 zero == 0x0007 || zero == 0x0700 || zero == 0x0008 || zero == 0x0800 ) 00432 { 00433 std::string msg 00434 = Util::Format("ACR/DICOM with no preamble: (%04x)\n", zero); 00435 gdcmWarningMacro( msg.c_str() ); 00436 return Fp; 00437 } 00438 00439 //DICOM 00440 Fp->seekg(126L, std::ios::cur); 00441 char dicm[4] = {' ',' ',' ',' '}; 00442 Fp->read(dicm, (size_t)4); 00443 if( Fp->eof() ) 00444 { 00445 CloseFile(); 00446 return 0; 00447 } 00448 if( memcmp(dicm, "DICM", 4) == 0 ) 00449 { 00450 HasDCMPreamble = true; 00451 return Fp; 00452 } 00453 00454 CloseFile(); 00455 gdcmWarningMacro( "Not DICOM/ACR (missing preamble)" << Filename.c_str()); 00456 00457 return 0; 00458 } |
|
Compares two documents, according to DicomDir rules.
Definition at line 598 of file gdcmDocument.cxx. References gdcm::DocEntrySet::GetEntryValue().
00599 { 00600 // Patient Name 00601 std::string s1 = GetEntryValue(0x0010,0x0010); 00602 std::string s2 = document.GetEntryValue(0x0010,0x0010); 00603 if(s1 < s2) 00604 { 00605 return true; 00606 } 00607 else if( s1 > s2 ) 00608 { 00609 return false; 00610 } 00611 else 00612 { 00613 // Patient ID 00614 s1 = GetEntryValue(0x0010,0x0020); 00615 s2 = document.GetEntryValue(0x0010,0x0020); 00616 if ( s1 < s2 ) 00617 { 00618 return true; 00619 } 00620 else if ( s1 > s2 ) 00621 { 00622 return false; 00623 } 00624 else 00625 { 00626 // Study Instance UID 00627 s1 = GetEntryValue(0x0020,0x000d); 00628 s2 = document.GetEntryValue(0x0020,0x000d); 00629 if ( s1 < s2 ) 00630 { 00631 return true; 00632 } 00633 else if( s1 > s2 ) 00634 { 00635 return false; 00636 } 00637 else 00638 { 00639 // Serie Instance UID 00640 s1 = GetEntryValue(0x0020,0x000e); 00641 s2 = document.GetEntryValue(0x0020,0x000e); 00642 if ( s1 < s2 ) 00643 { 00644 return true; 00645 } 00646 else if( s1 > s2 ) 00647 { 00648 return false; 00649 } 00650 } 00651 } 00652 } 00653 return false; 00654 } |
|
Parses a DocEntrySet (Zero-level DocEntries or SQ Item DocEntries).
Definition at line 775 of file gdcmDocument.cxx. References gdcm::DocEntrySet::AddEntry(), gdcm::ExplicitVR, Filetype, Fp, gdcmWarningMacro, gdcm::SQItem::GetBaseTagKey(), gdcm::SQItem::GetDepthLevel(), gdcm::DocEntry::GetElement(), gdcm::DocEntry::GetGroup(), gdcm::DocEntry::GetKey(), gdcm::DocEntry::GetOffset(), gdcm::DocEntry::GetReadLength(), gdcm::DocEntry::GetVR(), gdcm::DocEntry::IsItemDelimitor(), LoadDocEntry(), ParseSQ(), ReadNextDocEntry(), gdcm::SeqEntry::SetDelimitorMode(), gdcm::SeqEntry::SetDepthLevel(), gdcm::DocEntry::SetKey(), SkipToNextDocEntry(), and gdcm::VRKey. Referenced by Document(), and ParseSQ().
00777 { 00778 DocEntry *newDocEntry = 0; 00779 ValEntry *newValEntry; 00780 BinEntry *newBinEntry; 00781 SeqEntry *newSeqEntry; 00782 VRKey vr; 00783 bool used = false; 00784 00785 while (true) 00786 { 00787 if ( !delim_mode && ((long)(Fp->tellg())-offset) >= l_max) 00788 { 00789 break; 00790 } 00791 00792 used = true; 00793 newDocEntry = ReadNextDocEntry( ); 00794 00795 if ( !newDocEntry ) 00796 { 00797 break; 00798 } 00799 00800 vr = newDocEntry->GetVR(); 00801 newValEntry = dynamic_cast<ValEntry*>(newDocEntry); 00802 newBinEntry = dynamic_cast<BinEntry*>(newDocEntry); 00803 newSeqEntry = dynamic_cast<SeqEntry*>(newDocEntry); 00804 00805 if ( newValEntry || newBinEntry ) 00806 { 00807 if ( newBinEntry ) 00808 { 00809 if ( Filetype == ExplicitVR && 00810 !Global::GetVR()->IsVROfBinaryRepresentable(vr) ) 00811 { 00813 gdcmWarningMacro( std::hex << newDocEntry->GetGroup() 00814 << "|" << newDocEntry->GetElement() 00815 << " : Neither Valentry, nor BinEntry." 00816 "Probably unknown VR."); 00817 } 00818 00820 // When "this" is a Document the Key is simply of the 00821 // form ( group, elem )... 00822 if ( dynamic_cast< Document* > ( set ) ) 00823 { 00824 newBinEntry->SetKey( newBinEntry->GetKey() ); 00825 } 00826 // but when "this" is a SQItem, we are inserting this new 00827 // valEntry in a sequence item, and the key has the 00828 // generalized form (refer to \ref BaseTagKey): 00829 if (SQItem *parentSQItem = dynamic_cast< SQItem* > ( set ) ) 00830 { 00831 newBinEntry->SetKey( parentSQItem->GetBaseTagKey() 00832 + newBinEntry->GetKey() ); 00833 } 00834 00835 LoadDocEntry( newBinEntry ); 00836 if( !set->AddEntry( newBinEntry ) ) 00837 { 00838 //Expect big troubles if here 00839 //delete newBinEntry; 00840 used=false; 00841 } 00842 } 00843 else 00844 { 00846 // When "set" is a Document, then we are at the top of the 00847 // hierarchy and the Key is simply of the form ( group, elem )... 00848 if ( dynamic_cast< Document* > ( set ) ) 00849 { 00850 newValEntry->SetKey( newValEntry->GetKey() ); 00851 } 00852 // ...but when "set" is a SQItem, we are inserting this new 00853 // valEntry in a sequence item. Hence the key has the 00854 // generalized form (refer to \ref BaseTagKey): 00855 if (SQItem *parentSQItem = dynamic_cast< SQItem* > ( set ) ) 00856 { 00857 newValEntry->SetKey( parentSQItem->GetBaseTagKey() 00858 + newValEntry->GetKey() ); 00859 } 00860 00861 LoadDocEntry( newValEntry ); 00862 bool delimitor=newValEntry->IsItemDelimitor(); 00863 if( !set->AddEntry( newValEntry ) ) 00864 { 00865 // If here expect big troubles 00866 //delete newValEntry; //otherwise mem leak 00867 used=false; 00868 } 00869 00870 if (delimitor) 00871 { 00872 if(!used) 00873 delete newDocEntry; 00874 break; 00875 } 00876 if ( !delim_mode && ((long)(Fp->tellg())-offset) >= l_max) 00877 { 00878 if(!used) 00879 delete newDocEntry; 00880 break; 00881 } 00882 } 00883 00884 // Just to make sure we are at the beginning of next entry. 00885 SkipToNextDocEntry(newDocEntry); 00886 } 00887 else 00888 { 00889 // VR = "SQ" 00890 unsigned long l = newDocEntry->GetReadLength(); 00891 if ( l != 0 ) // don't mess the delim_mode for zero-length sequence 00892 { 00893 if ( l == 0xffffffff ) 00894 { 00895 delim_mode = true; 00896 } 00897 else 00898 { 00899 delim_mode = false; 00900 } 00901 } 00902 // no other way to create it ... 00903 newSeqEntry->SetDelimitorMode( delim_mode ); 00904 00905 // At the top of the hierarchy, stands a Document. When "set" 00906 // is a Document, then we are building the first depth level. 00907 // Hence the SeqEntry we are building simply has a depth 00908 // level of one: 00909 if (/*Document *dummy =*/ dynamic_cast< Document* > ( set ) ) 00910 { 00911 //(void)dummy; 00912 newSeqEntry->SetDepthLevel( 1 ); 00913 newSeqEntry->SetKey( newSeqEntry->GetKey() ); 00914 } 00915 // But when "set" is already a SQItem, we are building a nested 00916 // sequence, and hence the depth level of the new SeqEntry 00917 // we are building, is one level deeper: 00918 if (SQItem *parentSQItem = dynamic_cast< SQItem* > ( set ) ) 00919 { 00920 newSeqEntry->SetDepthLevel( parentSQItem->GetDepthLevel() + 1 ); 00921 newSeqEntry->SetKey( parentSQItem->GetBaseTagKey() 00922 + newSeqEntry->GetKey() ); 00923 } 00924 00925 if ( l != 0 ) 00926 { // Don't try to parse zero-length sequences 00927 ParseSQ( newSeqEntry, 00928 newDocEntry->GetOffset(), 00929 l, delim_mode); 00930 } 00931 if( !set->AddEntry( newSeqEntry ) ) 00932 { 00933 used = false; 00934 } 00935 if ( !delim_mode && ((long)(Fp->tellg())-offset) >= l_max) 00936 { 00937 if( !used ) 00938 delete newDocEntry; 00939 break; 00940 } 00941 } 00942 00943 if( !used ) 00944 delete newDocEntry; 00945 } 00946 } |
|
Parses a Sequence ( SeqEntry after SeqEntry).
Definition at line 952 of file gdcmDocument.cxx. References gdcm::SeqEntry::AddSQItem(), Fp, gdcm::SeqEntry::GetDepthLevel(), gdcm::DocEntry::GetKey(), gdcm::DocEntry::GetReadLength(), gdcm::DocEntry::IsSequenceDelimitor(), ParseDES(), ReadNextDocEntry(), gdcm::SQItem::SetBaseTagKey(), and gdcm::SeqEntry::SetDelimitationItem(). Referenced by ParseDES().
00954 { 00955 int SQItemNumber = 0; 00956 bool dlm_mod; 00957 long offsetStartCurrentSQItem = offset; 00958 00959 while (true) 00960 { 00961 // the first time, we read the fff0,e000 of the first SQItem 00962 DocEntry *newDocEntry = ReadNextDocEntry(); 00963 00964 if ( !newDocEntry ) 00965 { 00966 // FIXME Should warn user 00967 break; 00968 } 00969 if( delim_mode ) 00970 { 00971 if ( newDocEntry->IsSequenceDelimitor() ) 00972 { 00973 seqEntry->SetDelimitationItem( newDocEntry ); 00974 break; 00975 } 00976 } 00977 if ( !delim_mode && ((long)(Fp->tellg())-offset) >= l_max) 00978 { 00979 delete newDocEntry; 00980 break; 00981 } 00982 // create the current SQItem 00983 SQItem *itemSQ = new SQItem( seqEntry->GetDepthLevel() ); 00984 std::ostringstream newBase; 00985 newBase << seqEntry->GetKey() 00986 << "/" 00987 << SQItemNumber 00988 << "#"; 00989 itemSQ->SetBaseTagKey( newBase.str() ); 00990 unsigned int l = newDocEntry->GetReadLength(); 00991 00992 if ( l == 0xffffffff ) 00993 { 00994 dlm_mod = true; 00995 } 00996 else 00997 { 00998 dlm_mod = false; 00999 } 01000 // FIXME, TODO 01001 // when we're here, element fffe,e000 is already passed. 01002 // it's lost for the SQItem we're going to process !! 01003 01004 //ParseDES(itemSQ, newDocEntry->GetOffset(), l, dlm_mod); 01005 //delete newDocEntry; // FIXME well ... it's too late to use it ! 01006 01007 // Let's try :------------ 01008 // remove fff0,e000, created out of the SQItem 01009 delete newDocEntry; 01010 Fp->seekg(offsetStartCurrentSQItem, std::ios::beg); 01011 // fill up the current SQItem, starting at the beginning of fff0,e000 01012 ParseDES(itemSQ, offsetStartCurrentSQItem, l+8, dlm_mod); 01013 offsetStartCurrentSQItem = Fp->tellg(); 01014 // end try ----------------- 01015 01016 seqEntry->AddSQItem( itemSQ, SQItemNumber ); 01017 SQItemNumber++; 01018 if ( !delim_mode && ((long)(Fp->tellg())-offset ) >= l_max ) 01019 { 01020 break; 01021 } 01022 } 01023 } |
|
Prints the Header Entries (Dicom Elements) from the H Table.
Reimplemented from gdcm::Base. Reimplemented in gdcm::DicomDir. Definition at line 195 of file gdcmElementSet.cxx. References gdcm::DocEntry::Print(), gdcm::Base::SetPrintLevel(), and gdcm::ElementSet::TagHT. Referenced by gdcm::FileHelper::Print().
00196 { 00197 for( TagDocEntryHT::const_iterator i = TagHT.begin(); i != TagHT.end(); ++i) 00198 { 00199 DocEntry *entry = i->second; 00200 00201 entry->SetPrintLevel(PrintLevel); 00202 entry->Print(os); 00203 00204 if ( dynamic_cast<SeqEntry*>(entry) ) 00205 { 00206 // Avoid the newline for a sequence: 00207 continue; 00208 } 00209 os << std::endl; 00210 } 00211 } |
|
Reads a supposed to be 16 Bits integer (swaps it depending on processor endianness).
Definition at line 663 of file gdcmDocument.cxx. Referenced by LoadDocEntry(), ReadNextDocEntry(), and gdcm::File::ReadTag().
00665 { 00666 uint16_t g; 00667 Fp->read ((char*)&g, (size_t)2); 00668 if ( Fp->fail() ) 00669 { 00670 throw FormatError( "Document::ReadInt16()", " file error." ); 00671 } 00672 if( Fp->eof() ) 00673 { 00674 throw FormatError( "Document::ReadInt16()", "EOF." ); 00675 } 00676 g = SwapShort(g); 00677 return g; 00678 } |
|
Reads a supposed to be 32 Bits integer (swaps it depending on processor endianness).
Definition at line 685 of file gdcmDocument.cxx. Referenced by gdcm::File::ComputeRLEInfo(), LoadDocEntry(), and gdcm::File::ReadTagLength().
00687 { 00688 uint32_t g; 00689 Fp->read ((char*)&g, (size_t)4); 00690 if ( Fp->fail() ) 00691 { 00692 throw FormatError( "Document::ReadInt32()", " file error." ); 00693 } 00694 if( Fp->eof() ) 00695 { 00696 throw FormatError( "Document::ReadInt32()", "EOF." ); 00697 } 00698 g = SwapLong(g); 00699 return g; 00700 } |
|
Read the next tag but WITHOUT loading it's value (read the 'Group Number', the 'Element Number', gets the Dict Entry gets the VR, gets the length, gets the offset value).
Definition at line 1970 of file gdcmDocument.cxx. References gdcm::ExplicitVR, Filetype, FindDocEntryLength(), FindDocEntryVR(), Fp, gdcm::GDCM_UNKNOWN, gdcmWarningMacro, gdcm::DocEntrySet::GetDictEntry(), gdcm::DocEntry::GetElement(), gdcm::DocEntry::GetGroup(), gdcm::DictEntry::GetVR(), HandleBrokenEndian(), HandleOutOfGroup0002(), HasDCMPreamble, gdcm::DocEntrySet::NewBinEntry(), gdcm::DocEntrySet::NewSeqEntry(), gdcm::DocEntrySet::NewValEntry(), ReadInt16(), gdcm::DocEntry::SetImplicitVR(), and gdcm::DocEntry::SetOffset(). Referenced by ParseDES(), and ParseSQ().
01971 { 01972 uint16_t group; 01973 uint16_t elem; 01974 01975 try 01976 { 01977 group = ReadInt16(); 01978 elem = ReadInt16(); 01979 } 01980 catch ( FormatError e ) 01981 { 01982 // We reached the EOF (or an error occured) therefore 01983 // header parsing has to be considered as finished. 01984 return 0; 01985 } 01986 01987 // Sometimes file contains groups of tags with reversed endianess. 01988 HandleBrokenEndian(group, elem); 01989 01990 // In 'true DICOM' files Group 0002 is always little endian 01991 if ( HasDCMPreamble ) 01992 HandleOutOfGroup0002(group, elem); 01993 01994 std::string vr = FindDocEntryVR(); 01995 std::string realVR = vr; 01996 01997 if( vr == GDCM_UNKNOWN) 01998 { 01999 DictEntry *dictEntry = GetDictEntry(group,elem); 02000 if( dictEntry ) 02001 realVR = dictEntry->GetVR(); 02002 } 02003 02004 DocEntry *newEntry; 02005 if( Global::GetVR()->IsVROfSequence(realVR) ) 02006 newEntry = NewSeqEntry(group, elem); 02007 else if( Global::GetVR()->IsVROfStringRepresentable(realVR) ) 02008 newEntry = NewValEntry(group, elem,vr); 02009 else 02010 newEntry = NewBinEntry(group, elem,vr); 02011 02012 if( vr == GDCM_UNKNOWN ) 02013 { 02014 if( Filetype == ExplicitVR ) 02015 { 02016 // We thought this was explicit VR, but we end up with an 02017 // implicit VR tag. Let's backtrack. 02018 if ( newEntry->GetGroup() != 0xfffe ) 02019 { 02020 std::string msg; 02021 msg = Util::Format("Entry (%04x,%04x) should be Explicit VR\n", 02022 newEntry->GetGroup(), newEntry->GetElement()); 02023 gdcmWarningMacro( msg.c_str() ); 02024 } 02025 } 02026 newEntry->SetImplicitVR(); 02027 } 02028 02029 try 02030 { 02031 FindDocEntryLength(newEntry); 02032 } 02033 catch ( FormatError e ) 02034 { 02035 // Call it quits 02036 //std::cout << e; 02037 delete newEntry; 02038 return 0; 02039 } 02040 02041 newEntry->SetOffset(Fp->tellg()); 02042 02043 return newEntry; 02044 } |
|
Clear the hash table from given entry AND delete the entry.
Implements gdcm::DocEntrySet. Definition at line 89 of file gdcmElementSet.cxx. References gdcmWarningMacro, gdcm::DocEntry::GetKey(), gdcm::ElementSet::TagHT, and gdcm::TagKey. Referenced by gdcm::File::File(), and gdcm::DocEntryArchive::Restore().
00090 { 00091 const TagKey &key = entryToRemove->GetKey(); 00092 if( TagHT.count(key) == 1 ) 00093 { 00094 TagHT.erase(key); 00095 //gdcmWarningMacro( "One element erased."); 00096 delete entryToRemove; 00097 return true; 00098 } 00099 00100 gdcmWarningMacro( "Key not present"); 00101 return false ; 00102 } |
|
Clear the hash table from given entry BUT keep the entry.
Implements gdcm::DocEntrySet. Definition at line 108 of file gdcmElementSet.cxx. References gdcmWarningMacro, gdcm::DocEntry::GetKey(), gdcm::ElementSet::TagHT, and gdcm::TagKey. Referenced by gdcm::DicomDir::NewMeta(), gdcm::DocEntryArchive::Push(), and gdcm::File::Write().
00109 { 00110 const TagKey &key = entryToRemove->GetKey(); 00111 if( TagHT.count(key) == 1 ) 00112 { 00113 TagHT.erase(key); 00114 //gdcmWarningMacro( "One element erased."); 00115 return true; 00116 } 00117 00118 gdcmWarningMacro( "Key not present"); 00119 return false ; 00120 } |
|
Accesses an existing BinEntry (i.e. a Dicom Element) and modifies it's content with the given value.
Definition at line 228 of file gdcmDocEntrySet.cxx. References gdcm::GDCM_BINLOADED, gdcm::BinEntry::SetBinArea(), gdcm::DocEntry::SetLength(), and gdcm::ContentEntry::SetValue().
00229 { 00230 if(entry) 00231 { 00232 entry->SetBinArea(content); 00233 entry->SetLength(lgth); 00234 entry->SetValue(GDCM_BINLOADED); 00235 return true; 00236 } 00237 return false; 00238 } |
|
Accesses an existing DocEntry (i.e. a Dicom Element) through it's (group, element) and modifies it's content with the given value.
Definition at line 191 of file gdcmDocEntrySet.cxx. References gdcmWarningMacro, and gdcm::DocEntrySet::GetBinEntry(). Referenced by gdcm::DocEntrySet::InsertBinEntry(), and gdcm::FileHelper::SetBinEntry().
00193 { 00194 BinEntry *entry = GetBinEntry(group, elem); 00195 if (!entry ) 00196 { 00197 gdcmWarningMacro( "No corresponding ValEntry " << std::hex << group << 00198 "," << elem << " element (try promotion first)."); 00199 return false; 00200 } 00201 00202 return SetBinEntry(content,lgth,entry); 00203 } |
|
Accessor to Filename.
Definition at line 81 of file gdcmDocument.h. Referenced by gdcm::DicomDir::DicomDir().
00081 { Filename = fileName; } |
|
during parsing, Header Elements too long are not loaded in memory
Definition at line 1929 of file gdcmDocument.cxx. References MaxSizeLoadEntry. Referenced by Document().
01930 { 01931 if ( newSize < 0 ) 01932 { 01933 return; 01934 } 01935 if ((uint32_t)newSize >= (uint32_t)0xffffffff ) 01936 { 01937 MaxSizeLoadEntry = 0xffffffff; 01938 return; 01939 } 01940 MaxSizeLoadEntry = newSize; 01941 } |
|
Header Elements too long will not be printed.
Definition at line 1948 of file gdcmDocument.cxx. References MaxSizePrintEntry.
01949 { 01950 if ( newSize < 0 ) 01951 { 01952 return; 01953 } 01954 if ((uint32_t)newSize >= (uint32_t)0xffffffff ) 01955 { 01956 MaxSizePrintEntry = 0xffffffff; 01957 return; 01958 } 01959 MaxSizePrintEntry = newSize; 01960 } |
|
Sets the print level for the Dicom Header Elements.
Definition at line 45 of file gdcmBase.h. Referenced by gdcm::SQItem::Print(), gdcm::SeqEntry::Print(), gdcm::FileHelper::Print(), gdcm::ElementSet::Print(), and gdcm::DicomDir::Print().
00045 { PrintLevel = level; }; |
|
Set the shadow dictionary used.
Definition at line 210 of file gdcmDocument.cxx. References gdcm::DictKey, and RefShaDict.
00211 { 00212 RefShaDict = Global::GetDicts()->GetDict(dictName); 00213 return !RefShaDict; 00214 } |
|
Set the shadow dictionary used.
Definition at line 200 of file gdcmDocument.cxx. References RefShaDict.
00201 { 00202 RefShaDict = dict; 00203 return !RefShaDict; 00204 } |
|
Accesses an existing DocEntry (i.e. a Dicom Element) and modifies it's content with the given value.
Definition at line 211 of file gdcmDocEntrySet.cxx. References gdcm::ValEntry::SetValue().
00212 { 00213 if(entry) 00214 { 00215 entry->SetValue(content); 00216 return true; 00217 } 00218 return false; 00219 } |
|
Accesses an existing DocEntry (i.e. a Dicom Element) through it's (group, element) and modifies it's content with the given value.
Definition at line 169 of file gdcmDocEntrySet.cxx. References gdcmWarningMacro, and gdcm::DocEntrySet::GetValEntry(). Referenced by gdcm::File::AnonymizeFile(), Document(), gdcm::DocEntrySet::InsertValEntry(), gdcm::FileHelper::SetValEntry(), and gdcm::File::Write().
00171 { 00172 ValEntry *entry = GetValEntry(group, elem); 00173 if (!entry ) 00174 { 00175 gdcmWarningMacro( "No corresponding ValEntry " << std::hex << group << 00176 "," << elem << " element (try promotion first)."); 00177 return false; 00178 } 00179 return SetValEntry(content,entry); 00180 } |
|
skips bytes inside the source file
Definition at line 707 of file gdcmDocument.cxx. References Fp. Referenced by gdcm::File::ComputeJPEGFragmentInfo(), gdcm::File::ComputeRLEInfo(), and SkipDocEntry().
00708 { 00709 //FIXME don't dump the returned value 00710 Fp->seekg((long)nBytes, std::ios::cur); 00711 } |
|
Skip a given Header Entry.
Definition at line 1582 of file gdcmDocument.cxx. References gdcm::DocEntry::GetLength(), and SkipBytes().
01583 { 01584 SkipBytes(entry->GetLength()); 01585 } |
|
Skips to the beginning of the next Header Entry.
Definition at line 1592 of file gdcmDocument.cxx. References Fp, gdcm::DocEntry::GetGroup(), gdcm::DocEntry::GetOffset(), and gdcm::DocEntry::GetReadLength(). Referenced by ParseDES().
|
|
Swaps back the bytes of 4-byte long integer accordingly to processor order.
Definition at line 365 of file gdcmDocument.cxx. References gdcmErrorMacro, and SwapCode. Referenced by GetDocEntryValue().
00366 { 00367 switch (SwapCode) 00368 { 00369 case 1234 : 00370 break; 00371 case 4321 : 00372 a=( ((a<<24) & 0xff000000) | ((a<<8) & 0x00ff0000) | 00373 ((a>>8) & 0x0000ff00) | ((a>>24) & 0x000000ff) ); 00374 break; 00375 case 3412 : 00376 a=( ((a<<16) & 0xffff0000) | ((a>>16) & 0x0000ffff) ); 00377 break; 00378 case 2143 : 00379 a=( ((a<< 8) & 0xff00ff00) | ((a>>8) & 0x00ff00ff) ); 00380 break; 00381 default : 00382 gdcmErrorMacro( "Unset swap code:" << SwapCode ); 00383 a = 0; 00384 } 00385 return a; 00386 } |
|
Swaps the bytes so they agree with the processor order.
Definition at line 351 of file gdcmDocument.cxx. References SwapCode. Referenced by GetDocEntryValue(), and HandleOutOfGroup0002().
|
|
Change the Byte Swap code.
Definition at line 1904 of file gdcmDocument.cxx. References gdcmWarningMacro, and SwapCode. Referenced by HandleBrokenEndian(), and HandleOutOfGroup0002().
01905 { 01906 gdcmWarningMacro( "Switching Byte Swap code from "<< SwapCode); 01907 if ( SwapCode == 1234 ) 01908 { 01909 SwapCode = 4321; 01910 } 01911 else if ( SwapCode == 4321 ) 01912 { 01913 SwapCode = 1234; 01914 } 01915 else if ( SwapCode == 3412 ) 01916 { 01917 SwapCode = 2143; 01918 } 01919 else if ( SwapCode == 2143 ) 01920 { 01921 SwapCode = 3412; 01922 } 01923 } |
|
Unswaps back the bytes of 4-byte long integer so they agree with the processor order.
Definition at line 75 of file gdcmDocument.h.
00075 { return SwapLong(a);} |
|
Unswaps back the bytes of 2-bytes long integer so they agree with the processor order.
Definition at line 72 of file gdcmDocument.h.
00072 { return SwapShort(a);} |
|
Writes in a file all the Header Entries (Dicom Elements).
Reimplemented from gdcm::ElementSet. Definition at line 482 of file gdcmDocument.cxx. References gdcm::ExplicitVR, and gdcm::ImplicitVR.
00483 { 00484 // \TODO move the following lines (and a lot of others, to be written) 00485 // to a future function CheckAndCorrectHeader 00486 00487 // (necessary if user wants to write a DICOM V3 file 00488 // starting from an ACR-NEMA (V2) Header 00489 00490 if ( filetype == ImplicitVR || filetype == ExplicitVR ) 00491 { 00492 // writing Dicom File Preamble 00493 char filePreamble[128]; 00494 memset(filePreamble, 0, 128); 00495 fp->write(filePreamble, 128); 00496 fp->write("DICM", 4); 00497 } 00498 00499 /* 00500 * \todo rewrite later, if really usefull 00501 * - 'Group Length' element is optional in DICOM 00502 * - but un-updated odd groups lengthes can causes pb 00503 * (xmedcon breaker) 00504 * 00505 * if ( (filetype == ImplicitVR) || (filetype == ExplicitVR) ) 00506 * UpdateGroupLength(false,filetype); 00507 * if ( filetype == ACR) 00508 * UpdateGroupLength(true,ACR); 00509 */ 00510 00511 ElementSet::WriteContent(fp, filetype); // This one is recursive 00512 } |
|
List of element to Anonymize.
Definition at line 150 of file gdcmDocument.h. |
|
Refering underlying filename.
Definition at line 112 of file gdcmDocument.h. |
|
ACR, ACR_LIBIDO, ExplicitVR, ImplicitVR, Unknown.
Definition at line 138 of file gdcmDocument.h. Referenced by CheckSwap(), Document(), FindDocEntryVR(), GetFileType(), HandleOutOfGroup0002(), Initialize(), IsReadable(), ParseDES(), and ReadNextDocEntry(). |
|
File Pointer, opened during Document parsing.
Definition at line 135 of file gdcmDocument.h. Referenced by CheckSwap(), CloseFile(), Document(), FindDocEntryVR(), IsDocEntryAnInteger(), LoadDocEntry(), LoadDocEntrySafe(), LoadEntryBinArea(), OpenFile(), ParseDES(), ParseSQ(), ReadNextDocEntry(), SkipBytes(), and SkipToNextDocEntry(). |
|
whether we already parsed group 0002 (Meta Elements)
Definition at line 129 of file gdcmDocument.h. Referenced by Document(), and HandleOutOfGroup0002(). |
|
whether file has a DCM Preamble
Definition at line 132 of file gdcmDocument.h. Referenced by OpenFile(), and ReadNextDocEntry(). |
|
After opening the file, we read HEADER_LENGTH_TO_READ bytes.
Definition at line 141 of file gdcmDocument.h. |
|
Elements whose value is longer than MAX_SIZE_LOAD_ELEMENT_VALUE are NOT loaded.
Definition at line 51 of file gdcmDocument.cxx. Referenced by Document(). |
|
Elements whose value is longer than MAX_SIZE_PRINT_ELEMENT_VALUE are NOT printed.
Definition at line 52 of file gdcmDocument.cxx. |
|
Size threshold above which an element value will NOT be loaded in memory (to avoid loading the image/volume itself). By default, this upper bound is fixed to 1024 bytes (which might look reasonable when one considers the definition of the various VR contents).
Definition at line 197 of file gdcmDocument.h. Referenced by LoadDocEntry(), and SetMaxSizeLoadEntry(). |
|
Size threshold above which an element value will NOT be *printed* in order no to polute the screen output. By default, this upper bound is fixed to 64 bytes.
Definition at line 202 of file gdcmDocument.h. Referenced by SetMaxSizePrintEntry(). |
|
Amount of printed details for each Dicom Entries : 0 : stands for the least detail level.
Definition at line 53 of file gdcmBase.h. Referenced by gdcm::Base::Base(). |
|
Public dictionary used to parse this header.
Definition at line 188 of file gdcmDocument.h. Referenced by GetPubDict(), Initialize(), and ~Document(). |
|
Optional "shadow dictionary" (private elements) used to parse this header.
Definition at line 191 of file gdcmDocument.h. Referenced by GetShaDict(), Initialize(), SetShaDict(), and ~Document(). |
|
Swap code gives an information on the byte order of a supposed to be an int32, as it's read on disc (depending on the image Transfer Syntax *and* on the processor endianess) as opposed as it should in memory to be dealt as an int32. For instance :
Definition at line 126 of file gdcmDocument.h. Referenced by CheckSwap(), Document(), SwapLong(), SwapShort(), and SwitchByteSwapCode(). |