GDCM_NAME_SPACE::Document Class Reference

Derived by both gdcm::File and gdcm::DicomDir. More...

#include <gdcmDocument.h>

Inheritance diagram for GDCM_NAME_SPACE::Document:

Inheritance graph
[legend]
Collaboration diagram for GDCM_NAME_SPACE::Document:

Collaboration graph
[legend]
List of all members.

Public Types

typedef std::list< DicomElementListElements

Public Member Functions

virtual bool Load ()
 Loader. use SetLoadMode(), SetFileName() before !
DictGetPubDict ()
 Get the public dictionary used.
DictGetShaDict ()
 Get the shadow dictionary used.
bool SetShaDict (Dict *dict)
 Set the shadow dictionary used.
bool SetShaDict (DictKey const &dictName)
 Set the shadow dictionary used.
bool IsParsable ()
 This predicate tells us whether or not the current Document was properly parsed and contains at least *one* Dicom Element (and nothing more, sorry).
virtual bool IsReadable ()
 This predicate tells us whether or not the current Document was properly parsed and contains at least *one* Dicom Element (and nothing more, sorry).
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 )
const std::string & GetFileName () const
 Accessor to Filename.
virtual 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, or if the file starts with an ACR-NEMA look-like element.
bool CloseFile ()
 closes the file
void WriteContent (std::ofstream *fp, FileType type)
 Writes in a file all the 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 (DataEntry *entry)
 Loads (from disk) the element content when a string is not suitable.
void SetMaxSizeLoadEntry (long)
 during parsing, Header Elements too long are not loaded in memory
void AddForceLoadElement (uint16_t group, uint16_t elem)
 Adds a new element we want to load anyway.
bool operator< (Document &document)
 Loads the element while preserving the current underlying file position indicator as opposed to LoadDocEntry that modifies it Compares two documents, according to DicomDir rules.
void SetLoadMode (int mode)
 Sets the LoadMode as a boolean string. LD_NOSEQ, LD_NOSHADOW, LD_NOSHADOWSEQ ... (nothing more, right now) WARNING : before using NO_SHADOW, be sure *all* your files contain accurate values in the 0x0000 element (if any) of *each* Shadow Group. The parser will fail if the size is wrong !
virtual void Print (std::ostream &os=std::cout, std::string const &indent="")
 Prints the Header Entries (Dicom Elements) from the H Table.
void WriteContent (std::ofstream *fp, FileType filetype, bool insideMetaElements)
 Writes 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.
void ClearEntry ()
 delete all entries in the ElementSet
DocEntryGetFirstEntry ()
 Get the first entry while visiting *the* 'zero level' DocEntrySet (DocEntries out of any Sequence).
DocEntryGetNextEntry ()
 Get the next entry while visiting *the* 'zero level' DocEntrySet (DocEntries out of any Sequence).
DocEntryGetDocEntry (uint16_t group, uint16_t elem)
 retrieves a Dicom Element using (group, element)
bool IsEmpty ()
 Tells us if the ElementSet contains no entry.
int IsVRCoherent (uint16_t group)
 Checks whether *all* the DataEntries of the group have all the same type for VR (ImplicitVR or ExplicitVR).
virtual void Copy (DocEntrySet *set)
 Copies all the attributes from an other DocEntrySet.
virtual std::string GetEntryString (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 the DocEntrySet for the value length of a given tag..
DataEntryGetDataEntry (uint16_t group, uint16_t elem)
 Same as Document::GetDocEntry except it returns a result only when the corresponding entry is of type DataEntry.
SeqEntryGetSeqEntry (uint16_t group, uint16_t elem)
 Same as Document::GetDocEntry except it returns a result only when the corresponding entry is of type SeqEntry.
bool SetEntryString (std::string const &content, uint16_t group, uint16_t elem)
 Accesses an existing DocEntry (i.e. a Dicom Element) through its (group, element) and modifies its content with the given value.
bool SetEntryString (std::string const &content, DataEntry *entry)
 Accesses an existing DocEntry (i.e. a Dicom Element) and modifies its content with the given value.
bool SetEntryBinArea (uint8_t *content, int lgth, uint16_t group, uint16_t elem)
 Accesses an existing DocEntry (i.e. a Dicom Element) through its (group, element) and modifies its content with the given value.
bool SetEntryBinArea (uint8_t *content, int lgth, DataEntry *entry)
 Accesses an existing DataEntry (i.e. a Dicom Element) and modifies its content with the given value.
DataEntryInsertEntryString (std::string const &value, uint16_t group, uint16_t elem, VRKey const &vr=GDCM_VRUNKNOWN)
 Modifies the value of a given Doc Entry (Dicom Element) when it exists. Creates it with the given value when unexistant.
DataEntryInsertEntryBinArea (uint8_t *binArea, int lgth, uint16_t group, uint16_t elem, VRKey const &vr=GDCM_VRUNKNOWN)
 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.
SeqEntryInsertSeqEntry (uint16_t group, uint16_t elem)
 Creates a new gdcm::SeqEntry and adds it to the current DocEntrySet. (remove any existing entry with same group,elem).
virtual bool CheckIfEntryExist (uint16_t group, uint16_t elem)
 Checks if a given Dicom Element exists within the DocEntrySet.
DataEntryNewDataEntry (uint16_t group, uint16_t elem, VRKey const &vr=GDCM_VRUNKNOWN)
 Build a new DataEntry from all the low level arguments.
SeqEntryNewSeqEntry (uint16_t group, uint16_t elem)
 Build a new SeqEntry from all the low level arguments.
void Delete ()
 Delete the object.
void Register ()
 Register the object.
void Unregister ()
 Unregister the object.
const unsigned long & GetRefCount () const
 Get the reference counting.
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 neither loads nor parses the file. You should then invoke Document::Load.
virtual ~Document ()
 Canonical destructor.
virtual void CallStartMethod ()
 CallStartMethod.
virtual void CallProgressMethod ()
 CallProgressMethod.
virtual void CallEndMethod ()
 CallEndMethod.
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 nBytes)
 skips bytes inside the source file
int ComputeGroup0002Length ()
 Re-computes the length of the Dicom group 0002.
bool MayIWrite (uint16_t)
 Some group are illegal withing some Dicom Documents Only the Document knows it.
DictEntryGetDictEntry (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(s), if any.

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 :
  • a 'Little Endian' image, read with a little endian processor will have a SwapCode= 1234 (the order is OK; nothing to do)
  • a 'Little Endian' image, read with a big endian procesor will have a SwapCode= 4321 (the order is wrong; int32 an int16 must be swapped) note : values 2143, 4321, 3412 remain for the ACR-NEMA time, and the well known 'Bad Big Endian' and 'Bad Little Endian' codes.

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 UserAnonymizeList
 User supplied list of elements to Anonymize.
ListElements UserForceLoadList
 User supplied list of elements to force Load.
int LoadMode
 Bit string integer (each one considered as a boolean) Bit 0 : Skip Sequences, if possible Bit 1 : Skip Shadow Groups if possible Probabely, some more to add.
bool IsDocumentAlreadyLoaded
 Whether the gdcm::Document is already parsed/loaded : False from the creation of the gdcm::Document untill gdcm::Document:Load().
bool IsDocumentModified
 Whether the gdcm::Document was modified since the last Load().
float Progress
 value of the ??? for any progress bar
bool Abort
DictRefPubDict
 Public dictionary used to parse this header.
DictRefShaDict
 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).
uint16_t CurrentGroup
 to allow any inner method to know current tag Group number
uint16_t CurrentElem
 to allow any inner method to know current tag Element number
DocEntryPreviousDocEntry
 To be able to backtrack (Private Sequence, Implicit VR related pb).
int PrintLevel
 Amount of printed details for each Dicom Entries : 0 : stands for the least detail level.

Static Protected Attributes

static const unsigned int HEADER_LENGTH_TO_READ
 After opening the file, we read HEADER_LENGTH_TO_READ bytes.
static const unsigned int MAX_SIZE_LOAD_ELEMENT_VALUE = 0xfff
 Elements whose value is longer than MAX_SIZE_LOAD_ELEMENT_VALUE are NOT loaded.

Private Member Functions

 gdcmTypeMacro (Document)
void Initialize ()
 Loads all the needed Dictionaries.
bool DoTheLoadingDocumentJob ()
 Loader. (DEPRECATED : not to break the API) Performs the Loading Job (internal use only).
void ReadBegBuffer (size_t l) throw ( FormatError )
 Reads a given length of bytes (in order to avoid to many CPU time-consuming fread-s).
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.
double SwapDouble (double)
 Swaps back the bytes of 8-byte long 'double' 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.
void ParseDES (DocEntrySet *set, long offset, long l_max, bool delim_mode)
 Parses a DocEntrySet (Zero-level DocEntries or SQ Item DocEntries).
bool ParseSQ (SeqEntry *seq, long offset, long l_max, bool delim_mode)
 Parses a Sequence ( SeqEntry after SeqEntry).
void LoadDocEntry (DocEntry *e, bool forceLoad=false)
 Loads (or not) the element content depending if its length exceeds or not the value specified with Document::SetMaxSizeLoadEntry().
void FindDocEntryLength (DocEntry *e) throw ( FormatError )
 Find the value Length of the passed Doc Entry.
uint32_t FindDocEntryLengthOBOrOW () throw ( FormatUnexpected )
 Find the Length till the next sequence delimiter.
VRKey FindDocEntryVR ()
 Find the Value Representation of the current Dicom Element.
bool CheckDocEntryVR (const 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.
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.
DocEntryReadNextDocEntry ()
 Read the next tag 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).
uint16_t GetInt16 ()
 Gets from BegBuffer a supposed to be 16 Bits integer (swaps it depending on processor endianness).
uint32_t GetInt32 ()
 Gets from BegBuffer a supposed to be 32 Bits integer (swaps it depending on processor endianness).
void HandleBrokenEndian (uint16_t &group, uint16_t &elem)
 Handle broken private tag from Philips NTSCAN where the endianess is being switched 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.
DocEntryBacktrack (DocEntry *docEntry)
 When a private Sequence + Implicit VR is encountered we cannot guess it's a Sequence till we find the first Item Starter. We then backtrack to do the job.

Private Attributes

char BegBuffer [8]
 buffer to avoid some freads
char * PtrBegBuffer
size_t CurrentOffsetPosition
 to avoid time consuming ftellg
bool changeFromUN
 to indicate if last supposed to be UN DataElement is not (according to a private Dicom dictionary)
bool UnexpectedEOF
 whether an unexpected EOF was encountered

Detailed Description

Derived by both gdcm::File and gdcm::DicomDir.

Definition at line 42 of file gdcmDocument.h.


Member Typedef Documentation

typedef std::list<DicomElement> GDCM_NAME_SPACE::Document::ListElements
 

Definition at line 47 of file gdcmDocument.h.


Constructor & Destructor Documentation

GDCM_NAME_SPACE::Document::Document  )  [protected]
 

This default constructor neither loads nor parses the file. You should then invoke Document::Load.

Definition at line 56 of file gdcmDocument.cxx.

References changeFromUN, CurrentOffsetPosition, GDCM_NAME_SPACE::ExplicitVR, Filetype, Fp, Group0002Parsed, Initialize(), IsDocumentAlreadyLoaded, IsDocumentModified, GDCM_NAME_SPACE::LD_ALL, LoadMode, MAX_SIZE_LOAD_ELEMENT_VALUE, SetFileName(), SetMaxSizeLoadEntry(), SwapCode, and UnexpectedEOF.

00057          :ElementSet()
00058 {
00059    Fp = 0;
00060 
00061    SetMaxSizeLoadEntry(MAX_SIZE_LOAD_ELEMENT_VALUE);
00062    Initialize();
00063    SwapCode = 1234;
00064    Filetype = ExplicitVR;
00065    CurrentOffsetPosition = 0;
00066    // Load will set it to true if sucessfull
00067    Group0002Parsed = false;
00068    IsDocumentAlreadyLoaded = false;
00069    IsDocumentModified = true;
00070    LoadMode = LD_ALL; // default : load everything, later
00071    
00072    SetFileName("");
00073    changeFromUN=false;
00074    UnexpectedEOF=false;
00075 }

GDCM_NAME_SPACE::Document::~Document  )  [protected, virtual]
 

Canonical destructor.

Definition at line 80 of file gdcmDocument.cxx.

References CloseFile().

00081 {
00082    CloseFile();
00083 }


Member Function Documentation

bool GDCM_NAME_SPACE::ElementSet::AddEntry DocEntry newEntry  )  [virtual, inherited]
 

add a new Dicom Element pointer to the H Table

Parameters:
newEntry entry to add

Implements GDCM_NAME_SPACE::DocEntrySet.

Definition at line 101 of file gdcmElementSet.cxx.

References gdcmWarningMacro, GDCM_NAME_SPACE::DocEntry::GetKey(), and GDCM_NAME_SPACE::ElementSet::TagHT.

Referenced by GDCM_NAME_SPACE::DocEntryArchive::Push(), and GDCM_NAME_SPACE::DocEntryArchive::Restore().

00102 {
00103    const TagKey &key = newEntry->GetKey();
00104 
00105    if ( TagHT.count(key) == 1 )
00106    {
00107       gdcmWarningMacro( "Key already present: " << key );
00108       return false;
00109    }
00110    else
00111    {
00112       TagHT.insert(TagDocEntryHT::value_type(newEntry->GetKey(), newEntry));
00113       newEntry->Register();
00114       return true;
00115    }
00116 }

void GDCM_NAME_SPACE::Document::AddForceLoadElement uint16_t  group,
uint16_t  elem
 

Adds a new element we want to load anyway.

Parameters:
group Group number of the target tag.
elem Element number of the target tag.

Definition at line 304 of file gdcmDocument.cxx.

References GDCM_NAME_SPACE::DicomElement::Elem, GDCM_NAME_SPACE::DicomElement::Group, and UserForceLoadList.

00305 { 
00306    DicomElement el;
00307    el.Group = group;
00308    el.Elem  = elem;
00309    UserForceLoadList.push_back(el); 
00310 }

DocEntry * GDCM_NAME_SPACE::Document::Backtrack DocEntry docEntry  )  [private]
 

When a private Sequence + Implicit VR is encountered we cannot guess it's a Sequence till we find the first Item Starter. We then backtrack to do the job.

Parameters:
docEntry Item Starter that warned us

Definition at line 1408 of file gdcmDocument.cxx.

References GDCM_NAME_SPACE::RefCounter::Delete(), gdcmDebugMacro, GDCM_NAME_SPACE::DocEntry::GetElement(), GDCM_NAME_SPACE::DocEntry::GetGroup(), GDCM_NAME_SPACE::DocEntry::GetLength(), GDCM_NAME_SPACE::DocEntry::GetOffset(), GDCM_NAME_SPACE::DocEntrySet::NewSeqEntry(), GDCM_NAME_SPACE::DocEntrySet::PreviousDocEntry, GDCM_NAME_SPACE::ElementSet::RemoveEntry(), GDCM_NAME_SPACE::DocEntry::SetLength(), and GDCM_NAME_SPACE::DocEntry::SetOffset().

Referenced by ParseDES().

01409 {
01410    // delete the Item Starter, built erroneously out of any Sequence
01411    // it's not yet in the HTable/chained list
01412    docEntry->Delete();
01413 
01414    // Get all info we can from PreviousDocEntry
01415    uint16_t group = PreviousDocEntry->GetGroup();
01416    uint16_t elem  = PreviousDocEntry->GetElement();
01417    uint32_t lgt   = PreviousDocEntry->GetLength();
01418    long offset    = PreviousDocEntry->GetOffset();
01419 
01420    gdcmDebugMacro( "Backtrack :" << std::hex << group 
01421                                  << "|" << elem
01422                                  << " at offset 0x(" <<offset << ")" );
01423    RemoveEntry( PreviousDocEntry );
01424 
01425    // forge the Seq Entry
01426    DocEntry *newEntry = NewSeqEntry(group, elem);
01427    newEntry->SetLength(lgt);
01428    newEntry->SetOffset(offset);
01429 
01430    // Move back to the beginning of the Sequence
01431 
01432    Fp->seekg(offset, std::ios::beg); // Only for Shadow Implicit VR SQ
01433    return newEntry;
01434 }

void GDCM_NAME_SPACE::Document::CallEndMethod  )  [protected, virtual]
 

CallEndMethod.

Definition at line 1074 of file gdcmDocument.cxx.

References GDCM_NAME_SPACE::CMD_ENDPROGRESS, GDCM_NAME_SPACE::CommandManager::ExecuteCommand(), and Progress.

01075 {
01076    Progress = 1.0f;
01077    CommandManager::ExecuteCommand(this,CMD_ENDPROGRESS);
01078 }

void GDCM_NAME_SPACE::Document::CallProgressMethod  )  [protected, virtual]
 

CallProgressMethod.

Definition at line 1066 of file gdcmDocument.cxx.

References GDCM_NAME_SPACE::CMD_PROGRESS, and GDCM_NAME_SPACE::CommandManager::ExecuteCommand().

Referenced by GDCM_NAME_SPACE::DicomDir::CreateDicomDirChainedList().

01067 {
01068    CommandManager::ExecuteCommand(this,CMD_PROGRESS);
01069 }

void GDCM_NAME_SPACE::Document::CallStartMethod  )  [protected, virtual]
 

CallStartMethod.

Definition at line 1056 of file gdcmDocument.cxx.

References Abort, GDCM_NAME_SPACE::CMD_STARTPROGRESS, GDCM_NAME_SPACE::CommandManager::ExecuteCommand(), and Progress.

Referenced by GDCM_NAME_SPACE::DicomDir::CreateDicomDirChainedList().

01057 {
01058    Progress = 0.0f;
01059    Abort    = false;
01060    CommandManager::ExecuteCommand(this,CMD_STARTPROGRESS);
01061 }

bool GDCM_NAME_SPACE::Document::CheckDocEntryVR const VRKey vr  )  [private]
 

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.

Parameters:
vr Dicom Value Representation
Returns:
false if the VR is incorrect or if the VR isn't referenced otherwise, it returns true

Definition at line 1735 of file gdcmDocument.cxx.

References GDCM_NAME_SPACE::Global::GetVR(), and GDCM_NAME_SPACE::VR::IsValidVR().

01736 {
01737    return Global::GetVR()->IsValidVR(vr);
01738 }

bool GDCM_NAME_SPACE::DocEntrySet::CheckIfEntryExist uint16_t  group,
uint16_t  elem
[virtual, inherited]
 

Checks if a given Dicom Element exists within the DocEntrySet.

Parameters:
group Group number of the searched Dicom Element
elem Element number of the searched Dicom Element
Returns:
true is found

Definition at line 412 of file gdcmDocEntrySet.cxx.

References GDCM_NAME_SPACE::DocEntrySet::GetDocEntry().

00413 {
00414    return GetDocEntry(group,elem)!=NULL;
00415 }

bool GDCM_NAME_SPACE::Document::CheckSwap  )  [private]
 

Discover what the swap code is (among little endian, big endian, bad little endian, bad big endian). sw is set.

Returns:
false when we are absolutely sure it's neither ACR-NEMA nor DICOM true when we hope ours assuptions are OK

Definition at line 1912 of file gdcmDocument.cxx.

References GDCM_NAME_SPACE::ACR, CurrentOffsetPosition, GDCM_NAME_SPACE::ExplicitVR, Filetype, gdcmDebugMacro, gdcmWarningMacro, GDCM_NAME_SPACE::ImplicitVR, GDCM_NAME_SPACE::Util::IsCurrentProcessorBigEndian(), SwapCode, and GDCM_NAME_SPACE::Unknown.

Referenced by DoTheLoadingDocumentJob().

01913 {   
01914    uint32_t  s32;
01915    uint16_t  s16;
01916        
01917    char deb[256];
01918     
01919    // First, compare HostByteOrder and NetworkByteOrder in order to
01920    // determine if we shall need to swap bytes (i.e. the Endian type).
01921    bool net2host = Util::IsCurrentProcessorBigEndian();
01922          
01923    // The easiest case is the one of a 'true' DICOM header, we just have
01924    // to look for the string "DICM" inside the file preamble.
01925    Fp->read(deb, 256);
01926    
01927    char *entCur = deb + 128;
01928    if ( memcmp(entCur, "DICM", (size_t)4) == 0 )
01929    {
01930       gdcmDebugMacro( "Looks like DICOM Version3 (preamble + DCM)" );
01931       
01932       // Group 0002 should always be VR, and the first element 0000
01933       // Let's be carefull (so many wrong headers ...)
01934       // and determine the value representation (VR) : 
01935       // Let's skip to the first element (0002,0000) and check there if we find
01936       // "UL"  - or "OB" if the 1st one is (0002,0001) -,
01937       // in which case we (almost) know it is explicit VR.
01938       // WARNING: if it happens to be implicit VR then what we will read
01939       // is the length of the group. If this ascii representation of this
01940       // length happens to be "UL" then we shall believe it is explicit VR.
01941       // We need to skip :
01942       // * the 128 bytes of File Preamble (often padded with zeroes),
01943       // * the 4 bytes of "DICM" string,
01944       // * the 4 bytes of the first tag (0002, 0000),or (0002, 0001)
01945       // i.e. a total of  136 bytes.
01946       entCur = deb + 136;
01947      
01948       // group 0x0002 *is always* Explicit VR Sometimes,
01949       // even if elem 0002,0010 (Transfer Syntax) tells us the file is
01950       // *Implicit* VR  (see former 'gdcmData/icone.dcm')
01951       
01952       if ( memcmp(entCur, "UL", (size_t)2) == 0 ||
01953            memcmp(entCur, "OB", (size_t)2) == 0 ||
01954            memcmp(entCur, "UI", (size_t)2) == 0 ||
01955            memcmp(entCur, "CS", (size_t)2) == 0 )  // CS, to remove later
01956                                                    // when Write DCM *adds*
01957       // FIXME
01958       // Use Document::dicom_vr to test all the possibilities
01959       // instead of just checking for UL, OB and UI !? group 0000 
01960       {
01961          Filetype = ExplicitVR;
01962          gdcmDebugMacro( "Group 0002 : Explicit Value Representation");
01963       } 
01964       else 
01965       {
01966          Filetype = ImplicitVR;
01967          gdcmWarningMacro( "Group 0002 :Not an explicit Value Representation;"
01968                         << "Looks like a bugged Header!");
01969       }
01970       
01971       // Here, we assume that the file IS kosher Dicom !
01972       // (The meta elements - group 0x0002 - ARE little endian !)
01973       if ( net2host )
01974       {
01975          SwapCode = 4321;
01976          gdcmDebugMacro( "HostByteOrder != NetworkByteOrder, SwapCode = 4321");
01977       }
01978       else 
01979       {
01980          SwapCode = 1234;
01981          gdcmDebugMacro( "HostByteOrder = NetworkByteOrder, SwapCode = 1234");
01982       }
01983       
01984       // Position the file position indicator at first tag 
01985       // (i.e. after the file preamble and the "DICM" string).
01986 
01987       Fp->seekg ( 132L, std::ios::beg); // Once per Document
01988       CurrentOffsetPosition = 132;
01989       return true;
01990    } // ------------------------------- End of DicomV3 ----------------
01991 
01992    // Alas, this is not a DicomV3 file and whatever happens there is no file
01993    // preamble. We can reset the file position indicator to where the data
01994    // is (i.e. the beginning of the file).
01995 
01996    gdcmWarningMacro( "Not a Kosher DICOM Version3 file (no preamble)");
01997 
01998    Fp->seekg(0, std::ios::beg); // Once per ACR-NEMA Document
01999    CurrentOffsetPosition = 0;
02000    // Let's check 'No Preamble Dicom File' :
02001    // Should start with group 0x0002
02002    // and be Explicit Value Representation
02003 
02004    s16 = *((uint16_t *)(deb));
02005    SwapCode = 0;     
02006    switch ( s16 )
02007    {
02008       case 0x0002 :
02009          SwapCode = 1234;
02010          entCur = deb + 4;
02011          break;
02012       case 0x0200 :
02013          SwapCode = 4321;
02014          entCur = deb + 6;
02015     } 
02016 
02017    if ( SwapCode != 0 )
02018    {
02019       if ( memcmp(entCur, "UL", (size_t)2) == 0 ||
02020            memcmp(entCur, "OB", (size_t)2) == 0 ||
02021            memcmp(entCur, "UI", (size_t)2) == 0 ||
02022            memcmp(entCur, "SH", (size_t)2) == 0 ||
02023            memcmp(entCur, "AE", (size_t)2) == 0 ||
02024            memcmp(entCur, "OB", (size_t)2) == 0 )
02025          {
02026             Filetype = ExplicitVR;  // FIXME : not enough to say it's Explicit
02027                                     // Wait untill reading Transfer Syntax
02028             gdcmDebugMacro( "Group 0002 : Explicit Value Representation");
02029             return true;
02030           }
02031     }
02032 // ------------------------------- End of 'No Preamble' DicomV3 -------------
02033 
02034    // Our next best chance would be to be considering a 'clean' ACR/NEMA file.
02035    // By clean we mean that the length of the first group is written down.
02036    // If this is the case and since the length of the first group HAS to be
02037    // four (bytes), then determining the proper swap code is straightforward.
02038 
02039    entCur = deb + 4;
02040    // We assume the array of char we are considering contains the binary
02041    // representation of a 32 bits integer. Hence the following dirty
02042    // trick :
02043    s32 = *((uint32_t *)(entCur));
02044    switch( s32 )
02045    {
02046       case 0x00040000 :
02047          SwapCode = 3412;
02048          Filetype = ACR;
02049          return true;
02050       case 0x04000000 :
02051          SwapCode = 4321;
02052          Filetype = ACR;
02053          return true;
02054       case 0x00000400 :
02055          SwapCode = 2143;
02056          Filetype = ACR;
02057          return true;
02058       case 0x00000004 :
02059          SwapCode = 1234;
02060          Filetype = ACR;
02061          return true;
02062       default :
02063          // We are out of luck. It is not a DicomV3 nor a 'clean' ACR/NEMA file.
02064          // It is time for despaired wild guesses. 
02065          // So, let's check if this file wouldn't happen to be 'dirty' ACR/NEMA,
02066          //  i.e. the 'group length' element is not present :     
02067          
02068          //  check the supposed-to-be 'group number'
02069          //  in ( 0x0001 .. 0x0008 )
02070          //  to determine ' SwapCode' value .
02071          //  Only 0 or 4321 will be possible 
02072          //  (no oportunity to check for the formerly well known
02073          //  ACR-NEMA 'Bad Big Endian' or 'Bad Little Endian' 
02074          //  if unsuccessfull (i.e. neither 0x0002 nor 0x0200 etc-3, 4, ..., 8-)
02075          //  the file IS NOT ACR-NEMA nor DICOM V3
02076          //  Find a trick to tell it the caller...
02077       
02078          s16 = *((uint16_t *)(deb));
02079  
02080          gdcmDebugMacro("not a DicomV3 nor a 'clean' ACR/NEMA;"
02081                      << " (->despaired wild guesses !)");       
02082          switch ( s16 )
02083          {
02084             case 0x0001 :
02085             case 0x0002 :
02086             case 0x0003 :
02087             case 0x0004 :
02088             case 0x0005 :
02089             case 0x0006 :
02090             case 0x0007 :
02091             case 0x0008 :
02092             case 0x0028 :
02093                SwapCode = 1234;
02094                Filetype = ACR;
02095                return true;
02096             case 0x0100 :
02097             case 0x0200 :
02098             case 0x0300 :
02099             case 0x0400 :
02100             case 0x0500 :
02101             case 0x0600 :
02102             case 0x0700 :
02103             case 0x0800 :
02104             case 0x2800 :
02105                SwapCode = 4321;
02106                Filetype = ACR;
02107                return true;
02108             default :
02109     
02110                s16 = *((uint16_t *)(deb));
02111                if (s16 != 0x0000)
02112                    return false;
02113                s16 = *((uint16_t *)(deb+2));
02114 
02115                Fp->seekg ( 0L, std::ios::beg); // Once per Document
02116                CurrentOffsetPosition = 0;
02117                switch(s16)  // try an other trick!
02118                             // -> to be able to decode 0029|1010 DataElement
02119                             // -> and be not less cleaver than dcmdump ;-)
02120                {
02121                   case 0x0004 :
02122                      SwapCode = 1234; 
02123                      break;
02124                   case 0x0400 :
02125                      SwapCode = 3412;
02126                      break;      
02127                   default:
02128                      gdcmWarningMacro("ACR/NEMA unfound swap info (Hopeless !)");
02129                      Filetype = Unknown;
02130                      return false;
02131                }
02132                // Check if next 2 bytes are a VR
02133                // Probabely something more time-consuming exists with std::string
02134                const char VRvalues[] = "AEASCSDADSFLFDISLOLTPNSHSLSSSTTMUIULUSUTOBOWOFATUNSQ";
02135                int nbVal = 26;
02136                const char *pt = VRvalues;
02137                for (int i=0;i<nbVal;i++)
02138                {
02139                   if(*(deb+4) == *pt++)
02140                   if(*(deb+5) == *pt++) {
02141                      Filetype = ExplicitVR;
02142                      return true;       
02143                   }
02144 
02145               }
02146               Filetype = ImplicitVR;
02147               return true;       
02148          }
02149    }
02150 }

void GDCM_NAME_SPACE::ElementSet::ClearEntry  )  [virtual, inherited]
 

delete all entries in the ElementSet

Implements GDCM_NAME_SPACE::DocEntrySet.

Definition at line 139 of file gdcmElementSet.cxx.

References GDCM_NAME_SPACE::ElementSet::TagHT.

Referenced by GDCM_NAME_SPACE::ElementSet::Copy(), GDCM_NAME_SPACE::DicomDir::CreateDicomDir(), DoTheLoadingDocumentJob(), GDCM_NAME_SPACE::DicomDir::SetElements(), and GDCM_NAME_SPACE::ElementSet::~ElementSet().

00140 {
00141    for(TagDocEntryHT::iterator cc = TagHT.begin();cc != TagHT.end(); ++cc)
00142    {
00143       if ( cc->second )
00144       {
00145          cc->second->Unregister();
00146       }
00147    }
00148    TagHT.clear();
00149 }

bool GDCM_NAME_SPACE::Document::CloseFile  ) 
 

closes the file

Returns:
TRUE if the close was successfull

Definition at line 679 of file gdcmDocument.cxx.

Referenced by DoTheLoadingDocumentJob(), GDCM_NAME_SPACE::File::DoTheLoadingJob(), GDCM_NAME_SPACE::FileHelper::GetRaw(), and ~Document().

00680 {
00681    if ( Fp )
00682    {
00683       Fp->close();
00684       delete Fp;
00685       Fp = 0;
00686    }
00687    return true;
00688 }

int GDCM_NAME_SPACE::Document::ComputeGroup0002Length  )  [protected]
 

Re-computes the length of the Dicom group 0002.

Definition at line 1013 of file gdcmDocument.cxx.

References GDCM_NAME_SPACE::DocEntry::GetElement(), GDCM_NAME_SPACE::ElementSet::GetFirstEntry(), GDCM_NAME_SPACE::DocEntry::GetGroup(), GDCM_NAME_SPACE::DocEntry::GetLength(), GDCM_NAME_SPACE::ElementSet::GetNextEntry(), and GDCM_NAME_SPACE::DocEntry::GetVR().

Referenced by GDCM_NAME_SPACE::File::Write().

01014 {
01015    uint16_t gr;
01016    VRKey vr;
01017    
01018    int groupLength = 0;
01019    bool found0002 = false;   
01020   
01021    // for each zero-level Tag in the DCM Header
01022    DocEntry *entry = GetFirstEntry();
01023    while( entry )
01024    {
01025       gr = entry->GetGroup();
01026 
01027       if ( gr == 0x0002 )
01028       {
01029          found0002 = true;
01030 
01031          if ( entry->GetElement() != 0x0000 )
01032          {
01033             vr = entry->GetVR();
01034 
01035             //if ( (vr == "OB")||(vr == "OW")||(vr == "UT")||(vr == "SQ"))
01036             // (no SQ, OW, UT in group 0x0002;)
01037                if ( vr == "OB" ) 
01038                {
01039                   // explicit VR AND (OB, OW, SQ, UT) : 4 more bytes
01040                   groupLength +=  4;
01041                }
01042             groupLength += 2 + 2 + 4 + entry->GetLength();   
01043          }
01044       }
01045       else if (found0002 )
01046          break;
01047 
01048       entry = GetNextEntry();
01049    }
01050    return groupLength; 
01051 }

void GDCM_NAME_SPACE::ElementSet::Copy DocEntrySet set  )  [virtual, inherited]
 

Copies all the attributes from an other DocEntrySet.

Parameters:
set entry to copy from
Remarks:
The contained DocEntries a not copied, only referenced

Reimplemented from GDCM_NAME_SPACE::DocEntrySet.

Reimplemented in GDCM_NAME_SPACE::DicomDir.

Definition at line 201 of file gdcmElementSet.cxx.

References GDCM_NAME_SPACE::ElementSet::ClearEntry(), GDCM_NAME_SPACE::DocEntrySet::Copy(), GDCM_NAME_SPACE::ElementSet::ItTagHT, and GDCM_NAME_SPACE::ElementSet::TagHT.

Referenced by GDCM_NAME_SPACE::DicomDir::Copy().

00202 {
00203    // Remove all previous entries
00204    ClearEntry();
00205 
00206    DocEntrySet::Copy(set);
00207 
00208    ElementSet *eltSet = dynamic_cast<ElementSet *>(set);
00209    if( eltSet )
00210    {
00211       TagHT = eltSet->TagHT;
00212       for(ItTagHT = TagHT.begin();ItTagHT != TagHT.end();++ItTagHT)
00213       {
00214          (ItTagHT->second)->Register();
00215       }
00216    }
00217 }

void GDCM_NAME_SPACE::RefCounter::Delete  )  [inline, inherited]
 

Delete the object.

Remarks:
The object is deleted only if its reference counting is to zero

Definition at line 41 of file gdcmRefCounter.h.

Referenced by GDCM_NAME_SPACE::SerieHelper::AddFileName(), Backtrack(), GDCM_NAME_SPACE::FileHelper::CheckMandatoryElements(), GDCM_NAME_SPACE::FileHelper::CheckMandatoryEntry(), GDCM_NAME_SPACE::FileHelper::CopyMandatoryEntry(), GDCM_NAME_SPACE::Dict::DoTheLoadingJob(), GDCM_NAME_SPACE::FillDefaultDataDict(), GDCM_NAME_SPACE::DicomDirObject::FillObject(), vtkGdcmReader::GetFileInformation(), GDCM_NAME_SPACE::DocEntrySet::InsertEntryBinArea(), GDCM_NAME_SPACE::DocEntrySet::InsertEntryString(), GDCM_NAME_SPACE::DocEntrySet::InsertSeqEntry(), vtkGdcmReader::LoadFileInformation(), GDCM_NAME_SPACE::DicomDir::NewMeta(), GDCM_NAME_SPACE::DicomDirStudy::NewVisit(), ReadNextDocEntry(), GDCM_NAME_SPACE::DicomDir::SetElement(), GDCM_NAME_SPACE::FileHelper::SetMandatoryEntry(), GDCM_NAME_SPACE::FileHelper::SetWriteFileTypeToExplicitVR(), GDCM_NAME_SPACE::FileHelper::SetWriteFileTypeToImplicitVR(), GDCM_NAME_SPACE::FileHelper::SetWriteFileTypeToJPEG(), GDCM_NAME_SPACE::FileHelper::SetWriteFileTypeToJPEG2000(), GDCM_NAME_SPACE::FileHelper::SetWriteToLibido(), GDCM_NAME_SPACE::DicomDir::~DicomDir(), GDCM_NAME_SPACE::DictSet::~DictSet(), and GDCM_NAME_SPACE::Global::~Global().

00041 { Unregister(); }

bool GDCM_NAME_SPACE::Document::DoTheLoadingDocumentJob  )  [private]
 

Loader. (DEPRECATED : not to break the API) Performs the Loading Job (internal use only).

Returns:
false if file cannot be open or no swap info was found, or no tag was found.
FIXME --> FIXME : The difference between BinEntry and DataEntry --> no longer exists, but the alteration of Dicom Dictionary remains. --> Old comment restored on purpose. --> New one (replacing both BinEntry and ValEntry by DataEntry) --> had absolutely no meaning. --> The whole comment will be removed when the stuff is cleaned ! --> 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 decide of the semantics by deciding whether the following tags are either :
  • multivaluated US, and hence loaded as ValEntry, but afterwards also used as BinEntry, which requires the proper conversion,
  • OW, and hence loaded as BinEntry, but afterwards also used as ValEntry, which requires the proper conversion.

Definition at line 124 of file gdcmDocument.cxx.

References CheckSwap(), GDCM_NAME_SPACE::ElementSet::ClearEntry(), CloseFile(), Filename, Filetype, Fp, gdcmDebugMacro, gdcmErrorMacro, gdcmWarningMacro, GDCM_NAME_SPACE::DocEntrySet::GetDataEntry(), GDCM_NAME_SPACE::DocEntrySet::GetEntryString(), GDCM_NAME_SPACE::SeqEntry::GetFirstSQItem(), GDCM_NAME_SPACE::DocEntry::GetLength(), GDCM_NAME_SPACE::DocEntrySet::GetSeqEntry(), Group0002Parsed, IsDocumentAlreadyLoaded, IsDocumentModified, GDCM_NAME_SPACE::ElementSet::IsEmpty(), LoadEntryBinArea(), OpenFile(), ParseDES(), and GDCM_NAME_SPACE::Unknown.

Referenced by Load().

00125 {
00126    if ( ! IsDocumentModified ) // Nothing to do !
00127       return true;
00128 
00129    ClearEntry();
00130 
00131    Fp = 0;
00132    if ( !OpenFile() )
00133    {
00134       // warning already performed in OpenFile()
00135       Filetype = Unknown;
00136       return false;
00137    }
00138 
00139    Group0002Parsed = false;
00140 
00141    gdcmDebugMacro( "Starting parsing of file: " << Filename.c_str());
00142 
00143    // Computes the total length of the file
00144    Fp->seekg(0, std::ios::end);  // Once per Document !
00145    long lgt = Fp->tellg();       // Once per Document !   
00146    Fp->seekg(0, std::ios::beg);  // Once per Document !
00147 
00148    // CheckSwap returns a boolean 
00149    // (false if no swap info of any kind was found)
00150    if (! CheckSwap() )
00151    {
00152       gdcmWarningMacro( "Neither a DICOM V3 nor an ACR-NEMA file: " 
00153                    << Filename.c_str());
00154       CloseFile(); 
00155       return false;      
00156     }
00157 
00158    long beg = Fp->tellg();      // just after DICOM preamble (if any)
00159 
00160    lgt -= beg;                  // remaining length to parse    
00161 
00162    // Recursive call.
00163    // Loading is done during parsing
00164    ParseDES( this, beg, lgt, false); // delim_mode is first defaulted to false
00165 
00166    if ( IsEmpty() )
00167    { 
00168       gdcmErrorMacro( "No tag in internal hash table for: "
00169                         << Filename.c_str());
00170       CloseFile(); 
00171       return false;
00172    }
00173    IsDocumentAlreadyLoaded = true;
00174 
00175    //Fp->seekg(0, std::ios::beg);  // Once per Document!
00176    
00177    // Load 'non string' values
00178       
00179    std::string PhotometricInterpretation = GetEntryString(0x0028,0x0004);   
00180    if ( PhotometricInterpretation == "PALETTE COLOR " )
00181    {
00182    // FIXME
00183    // Probabely this line should be outside the 'if'
00184    // Try to find an image sample holding a 'gray LUT'
00185       LoadEntryBinArea(0x0028,0x1200);  // gray LUT
00186    
00209       
00210       // --> OB (byte aray) or OW (short int aray)
00211       // The actual VR has to be deduced from other entries.
00212       // Our way of loading them may fail in some cases :
00213       // We must or not SwapByte depending on other field values.
00214              
00215       LoadEntryBinArea(0x0028,0x1201);  // R    LUT
00216       LoadEntryBinArea(0x0028,0x1202);  // G    LUT
00217       LoadEntryBinArea(0x0028,0x1203);  // B    LUT
00218       
00219       // Segmented Red   Palette Color LUT Data
00220       LoadEntryBinArea(0x0028,0x1221);
00221       // Segmented Green Palette Color LUT Data
00222       LoadEntryBinArea(0x0028,0x1222);
00223       // Segmented Blue  Palette Color LUT Data
00224       LoadEntryBinArea(0x0028,0x1223);
00225    }
00226  
00227    //FIXME later : how to use it?
00228    SeqEntry *modLutSeq = GetSeqEntry(0x0028,0x3000); // Modality LUT Sequence
00229    if ( modLutSeq !=0 )
00230    {
00231       SQItem *sqi= modLutSeq->GetFirstSQItem();
00232       if ( sqi != 0 )
00233       {
00234          DataEntry *dataEntry = sqi->GetDataEntry(0x0028,0x3006); // LUT Data
00235          if ( dataEntry != 0 )
00236          {
00237             if ( dataEntry->GetLength() != 0 )
00238             {
00239                // FIXME : CTX dependent means : contexted dependant.
00240                //         see upper comment.
00241                LoadEntryBinArea(dataEntry);    //LUT Data (CTX dependent)
00242             }   
00243         }
00244      }      
00245    }
00246 
00247    // Force Loading some more elements if user asked to.
00248 
00249    GDCM_NAME_SPACE::DocEntry *d;
00250    for (ListElements::iterator it = UserForceLoadList.begin();  
00251                                it != UserForceLoadList.end();
00252                              ++it)
00253    {
00254       gdcmDebugMacro( "Force Load " << std::hex 
00255                        << (*it).Group << "|" <<(*it).Elem );
00256   
00257       d = GetDocEntry( (*it).Group, (*it).Elem);
00258   
00259       if ( d == NULL)
00260       {
00261          gdcmWarningMacro( "You asked to ForceLoad "  << std::hex
00262                           << (*it).Group <<"|"<< (*it).Elem
00263                           << " that doesn't exist" );
00264          continue;
00265       }
00266 
00267       LoadDocEntry(d, true);
00268    }
00269 
00270    CloseFile();
00271   
00272    // ----------------------------
00273    // Specific code to allow gdcm to read ACR-LibIDO formated images
00274    // Note: ACR-LibIDO is an extension of the ACR standard that was
00275    //       used at CREATIS. For the time being (say a couple of years)
00276    //       we keep this kludge to allow CREATIS users 
00277    //       reading their old images.
00278    //
00279    // if recognition code tells us we deal with a LibIDO image
00280    // we switch lineNumber and columnNumber
00281    //
00282    std::string RecCode;
00283    RecCode = GetEntryString(0x0008, 0x0010); // recognition code (RET)
00284    if (RecCode == "ACRNEMA_LIBIDO_1.1" ||
00285        RecCode == "CANRME_AILIBOD1_1." )  // for brain-damaged softwares
00286                                           // with "little-endian strings"
00287    {
00288          Filetype = ACR_LIBIDO; 
00289          std::string rows    = GetEntryString(0x0028, 0x0010);
00290          std::string columns = GetEntryString(0x0028, 0x0011);
00291          SetEntryString(columns, 0x0028, 0x0010);
00292          SetEntryString(rows   , 0x0028, 0x0011);
00293    }
00294    // --- End of ACR-LibIDO kludge --- 
00295    return true;
00296 }

void GDCM_NAME_SPACE::Document::FindDocEntryLength DocEntry entry  )  throw ( FormatError ) [private]
 

Find the value Length of the passed Doc Entry.

Parameters:
entry Header Entry whose length of the value shall be loaded.

Definition at line 1508 of file gdcmDocument.cxx.

References GDCM_NAME_SPACE::ExplicitVR, and gdcmWarningMacro.

Referenced by ReadNextDocEntry().

01510 {
01511    const VRKey &vr  = entry->GetVR();
01512    uint16_t length16;       
01513    if ( Filetype == ExplicitVR && !entry->IsImplicitVR() ) 
01514    {
01515    
01516    // WARNING :
01517    //
01518    // For some images, length of UN elements is coded on 2 bytes (instead of 4)
01519    // There are *not* readable !
01520    // You can make a quick and dirty patch, commenting out 
01521    //| vr == "UN"
01522    // in the following line.
01523    // (the 'straight' images will no longer be readable ...)
01524    
01525       if ( vr == "OB" || vr == "OW" || vr == "SQ" || vr == "UT" 
01526                                                           || vr == "UN" || changeFromUN == true)
01527       {
01528          changeFromUN = false;
01529          // The following reserved two bytes (see PS 3.5-2003, section
01530          // "7.1.2 Data element structure with explicit vr", p 27) must be
01531          // skipped before proceeding on reading the length on 4 bytes.
01532 
01533          //Fp->seekg( 2L, std::ios::cur); // Once per OW,OB,SQ DocEntry
01534          uint32_t length32 = ReadInt32(); // Once per OW,OB,SQ DocEntry
01535          CurrentOffsetPosition+=4;
01536          if ( (vr == "OB" || vr == "OW") && length32 == 0xffffffff ) 
01537          {
01538             uint32_t lengthOB;
01539             try 
01540             {
01541                lengthOB = FindDocEntryLengthOBOrOW();// for encapsulation of encoded pixel 
01542             }
01543             catch ( FormatUnexpected )
01544             {
01545                // Computing the length failed (this happens with broken
01546                // files like gdcm-JPEG-LossLess3a.dcm). We still have a
01547                // chance to get the pixels by deciding the element goes
01548                // until the end of the file. Hence we artificially fix the
01549                // the length and proceed.
01550                gdcmWarningMacro( " Computing the length failed for " << 
01551                                    entry->GetKey() <<" in " <<GetFileName());
01552 
01553                long currentPosition = Fp->tellg(); // Only for gdcm-JPEG-LossLess3a.dcm-like
01554                Fp->seekg(0L,std::ios::end);        // Only for gdcm-JPEG-LossLess3a.dcm-like
01555 
01556                long lengthUntilEOF = (long)(Fp->tellg())-currentPosition; // Only for gdcm-JPEG-LossLess3a.dcm-like
01557                Fp->seekg(currentPosition, std::ios::beg);                 // Only for gdcm-JPEG-LossLess3a.dcm-like
01558 
01559                entry->SetReadLength(lengthUntilEOF);
01560                entry->SetLength(lengthUntilEOF);
01561                return;
01562             }
01563             entry->SetReadLength(lengthOB);
01564             entry->SetLength(lengthOB);
01565             return;
01566          }
01567          FixDocEntryFoundLength(entry, length32); 
01568          return;
01569       }
01570       // Length is encoded on 2 bytes.
01571       //length16 = ReadInt16();
01572       length16 = GetInt16();
01573       // 0xffff means that we deal with 'No Length' Sequence 
01574       //        or 'No Length' SQItem
01575       if ( length16 == 0xffff) 
01576       {           
01577          length16 = 0;
01578       }
01579       FixDocEntryFoundLength( entry, (uint32_t)length16 );
01580       return;
01581    }
01582    else
01583    {
01584       // Either implicit VR or a non DICOM conformal (see note below) explicit
01585       // VR that ommited the VR of (at least) this element. Farts happen.
01586       // [Note: according to the part 5, PS 3.5-2001, section 7.1 p25
01587       // on Data elements "Implicit and Explicit VR Data Elements shall
01588       // not coexist in a Data Set and Data Sets nested within it".]
01589       // Length is on 4 bytes.
01590 
01591      // Well ... group 0002 is always coded in 'Explicit VR Litle Endian'
01592      // even if Transfer Syntax is 'Implicit VR ...'
01593      // --> Except for 'Implicit VR Big Endian Transfer Syntax GE Private' 
01594      //     where Group 0x0002 is *also* encoded in Implicit VR !
01595 
01596       FixDocEntryFoundLength( entry, GetInt32() /*ReadInt32()*/ );
01597       return;
01598    }
01599 }

uint32_t GDCM_NAME_SPACE::Document::FindDocEntryLengthOBOrOW  )  throw ( FormatUnexpected ) [private]
 

Find the Length till the next sequence delimiter.

Warning:
NOT end user intended method !
Returns:

Definition at line 1606 of file gdcmDocument.cxx.

References gdcmWarningMacro, GetInt16(), ReadBegBuffer(), ReadInt32(), and SkipBytes().

01608 {
01609    // See PS 3.5-2001, section A.4 p. 49 on encapsulation of encoded pixel data.
01610    
01611    long positionOnEntry = Fp->tellg(); // Only for OB,OW DataElements
01612 
01613    bool foundSequenceDelimiter = false;
01614    uint32_t totalLength = 0;
01615 
01616    while ( !foundSequenceDelimiter )
01617    {
01618       uint16_t group;
01619       uint16_t elem;
01620 
01621       try
01622       {
01623          //group = ReadInt16(); // Once per fragment (if any) of OB,OW DataElements
01624          //elem  = ReadInt16(); // Once per fragment (if any) of OB,OW DataElements 
01625          ReadBegBuffer(4); // Once per fragment (if any) of OB,OW DataElements
01626       }
01627       catch ( FormatError )
01628       {
01629          throw FormatError("Unexpected end of file encountered during ",
01630                            "Document::FindDocEntryLengthOBOrOW()");
01631       }
01632       group = GetInt16();
01633       elem  = GetInt16();
01634 
01635       // We have to decount the group and element we just read
01636       totalLength += 4;     
01637       if ( group != 0xfffe || ( ( elem != 0xe0dd ) && ( elem != 0xe000 ) ) )
01638       {
01639          gdcmWarningMacro( 
01640               "Neither an Item tag nor a Sequence delimiter tag on :" 
01641            << std::hex << group << " , " << elem 
01642            << ")" );
01643   
01644          Fp->seekg(positionOnEntry, std::ios::beg); // Once per fragment (if any) of OB,OW DataElements
01645          throw FormatUnexpected( 
01646                "Neither an Item tag nor a Sequence delimiter tag.");
01647       }
01648       if ( elem == 0xe0dd )
01649       {
01650          foundSequenceDelimiter = true;
01651       }
01652       uint32_t itemLength = ReadInt32(); // Once per fragment (if any) of OB,OW DataElements
01653       // We add 4 bytes since we just read the ItemLength with ReadInt32
01654       totalLength += itemLength + 4;
01655       SkipBytes(itemLength);
01656       
01657       if ( foundSequenceDelimiter )
01658       {
01659          break;
01660       }
01661    }
01662    Fp->seekg( positionOnEntry, std::ios::beg); // Only once for OB,OW DataElements
01663    return totalLength;
01664 }

VRKey GDCM_NAME_SPACE::Document::FindDocEntryVR  )  [private]
 

Find the Value Representation of the current Dicom Element.

Returns:
Value Representation of the current Entry

Definition at line 1670 of file gdcmDocument.cxx.

References CurrentGroup, CurrentOffsetPosition, GDCM_NAME_SPACE::ExplicitVR, Filetype, GDCM_NAME_SPACE::GDCM_VRUNKNOWN, gdcmWarningMacro, GDCM_NAME_SPACE::Global::GetVR(), and PtrBegBuffer.

Referenced by ReadNextDocEntry().

01671 {
01672    if ( Filetype != ExplicitVR )
01673    {
01674       return GDCM_VRUNKNOWN;
01675    }
01676 
01677    // Delimiters (0xfffe), are not explicit VR ... 
01678    if ( CurrentGroup == 0xfffe )
01679       return GDCM_VRUNKNOWN;
01680          
01681    //long positionOnEntry;     
01682    //if( Debug::GetWarningFlag() ) 
01683    //  positionOnEntry = Fp->tellg(); // Only in Warning Mode
01684    
01685    // Warning: we believe this is explicit VR (Value Representation) because
01686    // we used a heuristic that found "UL" in the first tag and/or
01687    // 'Transfer Syntax' told us it is.
01688    // Alas this doesn't guarantee that all the tags will be in explicit VR. 
01689    // In some cases one finds implicit VR tags mixed within an explicit VR file
01690    // Well...
01691    // 'Normaly' the only case is : group 0002 Explicit, and other groups Implicit
01692    //
01693    // Hence we make sure the present tag is in explicit VR and try to fix things
01694    // if it happens not to be the case.
01695 
01696    VRKey vr;
01697    //Fp->read(&(vr[0]),(size_t)2);
01698    vr[0] = *PtrBegBuffer++;
01699    vr[1] = *PtrBegBuffer++;
01700    
01701    //if ( !CheckDocEntryVR(vr) ) // avoid useless function call
01702    if ( !Global::GetVR()->IsValidVR(vr) )
01703    {
01704 /*   
01705 //      std::cout << "================================================================Unknown VR" 
01706                << std::hex << "0x(" 
01707                         << (unsigned int)vr[0] << "|" << (unsigned int)vr[1] 
01708                         << ")" << "for : " <<  CurrentGroup
01709                         << " at offset : 0x(" << positionOnEntry << ")"
01710                         << std::endl;
01711 */
01712       gdcmWarningMacro( "Unknown VR " << std::hex << "0x(" 
01713                         << (unsigned int)vr[0] << "|" << (unsigned int)vr[1] 
01714                         << ")"  
01715                         << " at offset : 0x(" << CurrentOffsetPosition-4<< ") for group " << CurrentGroup
01716                         );
01717 
01718       //Fp->seekg(positionOnEntry, std::ios::beg); //JPRx
01719       //Fp->seekg((long)-2, std::ios::cur);// only for unrecognized VR (?!?) 
01720                                          //see :MR_Philips_Intera_PrivateSequenceExplicitVR.dcm
01721       PtrBegBuffer-=2;
01722       return GDCM_VRUNKNOWN;
01723    }
01724    return vr;
01725 }

void GDCM_NAME_SPACE::Document::FixDocEntryFoundLength DocEntry entry,
uint32_t  foundLength
[private]
 

When the length of an element value is obviously wrong (because the parser went Jabberwocky) one can hope improving things by applying some heuristics.

Parameters:
entry entry to check
foundLength first assumption about length (before bug fix, or set to zero if =0xffffffff)

Definition at line 1773 of file gdcmDocument.cxx.

References gdcmErrorMacro, gdcmWarningMacro, GDCM_NAME_SPACE::DocEntry::GetElement(), GDCM_NAME_SPACE::DocEntry::GetGroup(), GDCM_NAME_SPACE::DocEntry::GetVR(), GDCM_NAME_SPACE::DocEntry::SetLength(), and GDCM_NAME_SPACE::DocEntry::SetReadLength().

01775 {
01776    entry->SetReadLength( foundLength );// will be updated only if a bug is found
01777    
01778    if ( foundLength == 0xffffffff)
01779    {
01780       //foundLength = 0;
01781       //entry->SetLength(foundLength);
01782       entry->SetLength(0);
01783       return;  // return ASAP; don't waist time on useless tests
01784    }
01785       
01786    uint16_t gr   = entry->GetGroup();
01787    uint16_t elem = entry->GetElement(); 
01788      
01789    if ( foundLength % 2)
01790    {
01791       gdcmWarningMacro( "Warning : Tag with uneven length " << foundLength
01792         <<  " in x(" << std::hex << gr << "," << elem <<")");
01793    }
01794       
01796    // Allthough not recent many such GE corrupted images are still present
01797    // on Creatis hard disks. Hence this fix shall remain when such images
01798    // are no longer in use (we are talking a few years, here)...
01799    // Note: XMedCon probably uses such a trick since it is able to read
01800    //       those pesky GE images ...
01801    if ( foundLength == 13)
01802    {
01803       // Only happens for this length !
01804       if ( gr != 0x0008 || ( elem != 0x0070 && elem != 0x0080 ) )
01805       {
01806          foundLength = 10;
01807          entry->SetReadLength(10); // a bug is to be fixed !?
01808       }
01809    }
01810 
01812    // Occurence of such images is quite low (unless one leaves close to a
01813    // 'Leonardo' source. Hence, one might consider commenting out the
01814    // following fix on efficiency reasons.
01815    else if ( gr == 0x0009 && ( elem == 0x1113 || elem == 0x1114 ) )
01816    { 
01817    // Ideally we should check we are in Explicit and double check
01818    // that VR=UL... this is done properly in gdcm2
01819       if( foundLength == 6 )
01820       {
01821          gdcmWarningMacro( "Replacing Length from 6 into 4" );
01822          foundLength = 4;
01823          entry->SetReadLength(4); // a bug is to be fixed !
01824       } 
01825       else if ( foundLength%4 )
01826       {
01827         gdcmErrorMacro( "This looks like to a buggy Siemens DICOM file."
01828         "The length of this tag seems to be wrong" );
01829       }
01830    }
01831 
01832    else if ( entry->GetVR() == "SQ" )
01833    {
01834       foundLength = 0;      // ReadLength is unchanged
01835    }
01836 
01838    // "fffe|xxxx" which is just a marker. Delimiters length should not be
01839    // taken into account.
01840    else if ( gr == 0xfffe )
01841    {
01842      // According to the norm, fffe|0000 shouldn't exist. BUT the Philips
01843      // image gdcmData/gdcm-MR-PHILIPS-16-Multi-Seq.dcm happens to
01844      // causes extra troubles...
01845      if ( elem != 0x0000 )
01846      {
01847         foundLength = 0;
01848      }
01849      else
01850      {
01851         foundLength=12; // to skip the mess that follows this bugged Tag !
01852      }
01853    }
01854    entry->SetLength(foundLength);
01855 }

GDCM_NAME_SPACE::Document::gdcmTypeMacro Document   )  [private]
 

DataEntry * GDCM_NAME_SPACE::DocEntrySet::GetDataEntry uint16_t  group,
uint16_t  elem
[inherited]
 

Same as Document::GetDocEntry except it returns a result only when the corresponding entry is of type DataEntry.

Parameters:
group Group number of the searched Dicom Element
elem Element number of the searched Dicom Element
Returns:
When present, the corresponding DataEntry.

Definition at line 103 of file gdcmDocEntrySet.cxx.

References GDCM_NAME_SPACE::DocEntrySet::GetDocEntry().

Referenced by GDCM_NAME_SPACE::FileHelper::CheckMandatoryElements(), GDCM_NAME_SPACE::FileHelper::CheckMandatoryEntry(), DoTheLoadingDocumentJob(), GDCM_NAME_SPACE::File::GetBitsAllocated(), GDCM_NAME_SPACE::File::GetBitsStored(), GDCM_NAME_SPACE::DocEntrySet::GetEntryBinArea(), GDCM_NAME_SPACE::File::GetHighBitPosition(), GDCM_NAME_SPACE::File::GetPlanarConfiguration(), GDCM_NAME_SPACE::File::GetRescaleIntercept(), GDCM_NAME_SPACE::File::GetSamplesPerPixel(), GDCM_NAME_SPACE::File::GetTSize(), GDCM_NAME_SPACE::File::GetXOrigin(), GDCM_NAME_SPACE::File::GetXSize(), GDCM_NAME_SPACE::File::GetXSpacing(), GDCM_NAME_SPACE::File::GetYOrigin(), GDCM_NAME_SPACE::File::GetYSize(), GDCM_NAME_SPACE::File::GetYSpacing(), GDCM_NAME_SPACE::File::GetZOrigin(), GDCM_NAME_SPACE::File::GetZSize(), GDCM_NAME_SPACE::File::GetZSpacing(), GDCM_NAME_SPACE::File::IsSignedPixelData(), GDCM_NAME_SPACE::ElementSet::Print(), GDCM_NAME_SPACE::DocEntrySet::SetEntryBinArea(), GDCM_NAME_SPACE::DocEntrySet::SetEntryString(), GDCM_NAME_SPACE::FileHelper::SetWriteToLibido(), GDCM_NAME_SPACE::FileHelper::SetWriteToNoLibido(), GDCM_NAME_SPACE::FileHelper::Write(), GDCM_NAME_SPACE::File::Write(), and GDCM_NAME_SPACE::DicomDirMeta::WriteContent().

00104 {
00105    DocEntry *currentEntry = GetDocEntry(group, elem);
00106    if ( !currentEntry )
00107       return NULL;
00108 
00109    return dynamic_cast<DataEntry*>(currentEntry);
00110 }

DictEntry * GDCM_NAME_SPACE::DocEntrySet::GetDictEntry uint16_t  group,
uint16_t  elem
[protected, inherited]
 

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(s), if any.

Parameters:
group Group number of the searched DictEntry
elem Element number of the searched DictEntry
Returns:
Corresponding DictEntry when it exists, NULL otherwise.
Remarks:
The returned DictEntry is registered when existing
Todo:
store the DefaultPubDict somwhere, in order not to access the HTable every time ! --> Done!

Definition at line 473 of file gdcmDocEntrySet.cxx.

References gdcmWarningMacro, GDCM_NAME_SPACE::DictSet::GetDefaultPubDict(), GDCM_NAME_SPACE::Global::GetDicts(), GDCM_NAME_SPACE::Dict::GetEntry(), and GDCM_NAME_SPACE::RefCounter::Register().

Referenced by ReadNextDocEntry().

00474 {
00475    DictEntry *found = 0;
00478    Dict *pubDict = Global::GetDicts()->GetDefaultPubDict();
00479    if (!pubDict) 
00480    {
00481       gdcmWarningMacro( "We SHOULD have a default dictionary");
00482    }
00483    else
00484    {
00485       found = pubDict->GetEntry(group, elem);
00486       if( found )
00487          found->Register();
00488    }
00489    return found;
00490 }

DocEntry * GDCM_NAME_SPACE::ElementSet::GetDocEntry uint16_t  group,
uint16_t  elem
[virtual, inherited]
 

retrieves a Dicom Element using (group, element)

Parameters:
group Group number of the searched Dicom Element
elem Element number of the searched Dicom Element
Returns:

Implements GDCM_NAME_SPACE::DocEntrySet.

Definition at line 186 of file gdcmElementSet.cxx.

References GDCM_NAME_SPACE::ElementSet::TagHT, and GDCM_NAME_SPACE::DictEntry::TranslateToKey().

Referenced by GDCM_NAME_SPACE::File::AnonymizeFile(), GDCM_NAME_SPACE::File::AnonymizeNoLoad(), GDCM_NAME_SPACE::FileHelper::CopyDataEntry(), GDCM_NAME_SPACE::DicomDir::CreateDicomDir(), GDCM_NAME_SPACE::File::DoTheLoadingJob(), GDCM_NAME_SPACE::DicomDir::DoTheLoadingJob(), GDCM_NAME_SPACE::File::GetPixelAreaLength(), GDCM_NAME_SPACE::File::GetPixelOffset(), GetTransferSyntax(), GDCM_NAME_SPACE::File::HasLUT(), IsDicomV3(), IsPapyrus(), GDCM_NAME_SPACE::File::IsReadable(), LoadEntryBinArea(), GDCM_NAME_SPACE::DocEntryArchive::Push(), and GDCM_NAME_SPACE::DocEntryArchive::Restore().

00187 {
00188    TagKey key = DictEntry::TranslateToKey(group, elem);
00189    TagDocEntryHT::iterator it = TagHT.find(key);
00190 
00191    if ( it!=TagHT.end() )
00192       return it->second;
00193    return NULL;
00194 }

void * GDCM_NAME_SPACE::DocEntrySet::GetEntryBinArea uint16_t  group,
uint16_t  elem
[virtual, inherited]
 

Gets (from Header) a 'non string' element value.

Parameters:
group group number of the Entry
elem element number of the Entry
Returns:
Pointer to the 'non string' area

Definition at line 73 of file gdcmDocEntrySet.cxx.

References GDCM_NAME_SPACE::DataEntry::GetBinArea(), and GDCM_NAME_SPACE::DocEntrySet::GetDataEntry().

00074 {
00075    DataEntry *entry = GetDataEntry(group, elem);
00076    if ( entry )
00077       return entry->GetBinArea();
00078    return 0;
00079 }

int GDCM_NAME_SPACE::DocEntrySet::GetEntryLength uint16_t  group,
uint16_t  elem
[virtual, inherited]
 

Searches within the DocEntrySet for the value length of a given tag..

Parameters:
group Group number of the searched tag.
elem Element number of the searched tag.
Returns:
Corresponding element length; -1 if not found

Definition at line 88 of file gdcmDocEntrySet.cxx.

References GDCM_NAME_SPACE::DocEntrySet::GetDocEntry(), and GDCM_NAME_SPACE::DocEntry::GetLength().

Referenced by GDCM_NAME_SPACE::DicomDir::SetElement(), and GDCM_NAME_SPACE::File::Write().

00089 {
00090    DocEntry *entry = GetDocEntry(group, elem);
00091    if ( entry )
00092       return entry->GetLength();
00093    return -1;
00094 }

std::string GDCM_NAME_SPACE::DocEntrySet::GetEntryString uint16_t  group,
uint16_t  elem
[virtual, inherited]
 

Get the "std::string representable" value of the Dicom entry.

Parameters:
group Group number of the searched tag.
elem Element number of the searched tag.
Returns:
Corresponding element value when it exists, and the string GDCM_UNFOUND otherwise.

Definition at line 51 of file gdcmDocEntrySet.cxx.

References GDCM_NAME_SPACE::GDCM_NOTLOADED, GDCM_NAME_SPACE::GDCM_UNFOUND, GDCM_NAME_SPACE::GDCM_UNREAD, GDCM_NAME_SPACE::DocEntrySet::GetDocEntry(), GDCM_NAME_SPACE::DataEntry::GetString(), GDCM_NAME_SPACE::DataEntry::IsNotLoaded(), GDCM_NAME_SPACE::DataEntry::IsUnfound(), and GDCM_NAME_SPACE::DataEntry::IsUnread().

Referenced by GDCM_NAME_SPACE::SerieHelper::AddFile(), GDCM_NAME_SPACE::File::AnonymizeFile(), GDCM_NAME_SPACE::FileHelper::CheckMandatoryElements(), GDCM_NAME_SPACE::SerieHelper::CreateUniqueSeriesIdentifier(), GDCM_NAME_SPACE::SerieHelper::CreateUserDefinedFileIdentifier(), DoTheLoadingDocumentJob(), GDCM_NAME_SPACE::File::DoTheLoadingJob(), GDCM_NAME_SPACE::DirList::Explore(), GDCM_NAME_SPACE::File::GetImageNumber(), GDCM_NAME_SPACE::File::GetImageOrientationPatient(), GDCM_NAME_SPACE::File::GetImagePositionPatient(), GDCM_NAME_SPACE::File::GetLUTNbits(), GDCM_NAME_SPACE::File::GetModality(), GDCM_NAME_SPACE::File::GetNumberOfScalarComponents(), GDCM_NAME_SPACE::File::GetNumberOfScalarComponentsRaw(), GDCM_NAME_SPACE::File::GetPixelSize(), GDCM_NAME_SPACE::File::GetPixelType(), GDCM_NAME_SPACE::File::GetRescaleSlope(), GDCM_NAME_SPACE::File::GetRescaleSlopeIntercept(), GDCM_NAME_SPACE::File::GetSpacing(), GetTransferSyntaxName(), GDCM_NAME_SPACE::File::GetXSpacing(), GDCM_NAME_SPACE::File::GetYSpacing(), GDCM_NAME_SPACE::File::IsMonochrome(), GDCM_NAME_SPACE::File::IsMonochrome1(), GDCM_NAME_SPACE::File::IsPaletteColor(), GDCM_NAME_SPACE::File::IsReadable(), GDCM_NAME_SPACE::File::IsYBRFull(), operator<(), and GDCM_NAME_SPACE::DicomDir::SetElement().

00052 {
00053    DataEntry *entry = dynamic_cast<DataEntry *>(GetDocEntry(group,elem));
00054    if ( entry )
00055    {
00056       if( entry->IsNotLoaded() )
00057          return GDCM_NOTLOADED;
00058       if( entry->IsUnfound() )
00059          return GDCM_UNFOUND;
00060       if( entry->IsUnread() )
00061          return GDCM_UNREAD;
00062       return entry->GetString();
00063    }
00064    return GDCM_UNFOUND;
00065 }

const std::string& GDCM_NAME_SPACE::Document::GetFileName  )  const [inline]
 

Accessor to Filename.

Definition at line 78 of file gdcmDocument.h.

Referenced by GDCM_NAME_SPACE::DicomDir::DoTheLoadingJob(), GDCM_NAME_SPACE::SerieHelper::FileNameGreaterThan(), GDCM_NAME_SPACE::SerieHelper::FileNameLessThan(), IsParsable(), GDCM_NAME_SPACE::DicomDir::IsReadable(), Load(), vtkGdcmReader::LoadImageInMemory(), GDCM_NAME_SPACE::DicomDir::ParseDirectory(), GDCM_NAME_SPACE::DicomDir::SetElement(), vtkGdcmReader::TestFileInformation(), and userSuppliedLessThanFunction2().

00078 { return Filename; }

FileType GDCM_NAME_SPACE::Document::GetFileType  ) 
 

returns the File Type (ACR, ACR_LIBIDO, ExplicitVR, ImplicitVR, Unknown)

Returns:
the FileType code

Definition at line 417 of file gdcmDocument.cxx.

References Filetype.

00418 {
00419    return Filetype;
00420 }

DocEntry * GDCM_NAME_SPACE::ElementSet::GetFirstEntry  )  [virtual, inherited]
 

Get the first entry while visiting *the* 'zero level' DocEntrySet (DocEntries out of any Sequence).

Returns:
The first DocEntry if found, otherwhise NULL

Implements GDCM_NAME_SPACE::DocEntrySet.

Definition at line 156 of file gdcmElementSet.cxx.

References GDCM_NAME_SPACE::ElementSet::ItTagHT, and GDCM_NAME_SPACE::ElementSet::TagHT.

Referenced by ComputeGroup0002Length(), GDCM_NAME_SPACE::DicomDir::DoTheLoadingJob(), GDCM_NAME_SPACE::DicomDir::NewMeta(), and GDCM_NAME_SPACE::Validator::SetInput().

00157 {
00158    ItTagHT = TagHT.begin();
00159    if (ItTagHT != TagHT.end())
00160       return  ItTagHT->second;
00161    return NULL;
00162 }

uint16_t GDCM_NAME_SPACE::Document::GetInt16  )  [private]
 

Gets from BegBuffer a supposed to be 16 Bits integer (swaps it depending on processor endianness).

Returns:
read value

Definition at line 968 of file gdcmDocument.cxx.

References PtrBegBuffer, and SwapShort().

Referenced by FindDocEntryLengthOBOrOW(), and ReadNextDocEntry().

00969 {
00970    uint16_t g = *((uint16_t*)PtrBegBuffer);
00971    g = SwapShort(g);
00972    PtrBegBuffer+=2; 
00973    return g;
00974 }

uint32_t GDCM_NAME_SPACE::Document::GetInt32  )  [private]
 

Gets from BegBuffer a supposed to be 32 Bits integer (swaps it depending on processor endianness).

Returns:
read value

Definition at line 1002 of file gdcmDocument.cxx.

References PtrBegBuffer, and SwapLong().

01003 {
01004    uint32_t g = *((uint32_t*)PtrBegBuffer);
01005    g = SwapLong(g); 
01006    PtrBegBuffer+=4;
01007    return g;
01008 }

DocEntry * GDCM_NAME_SPACE::ElementSet::GetNextEntry  )  [virtual, inherited]
 

Get the next entry while visiting *the* 'zero level' DocEntrySet (DocEntries out of any Sequence).

Note:
: meaningfull only if GetFirstEntry already called
Returns:
The next DocEntry if found, otherwhise NULL

Implements GDCM_NAME_SPACE::DocEntrySet.

Definition at line 170 of file gdcmElementSet.cxx.

References gdcmAssertMacro, GDCM_NAME_SPACE::ElementSet::ItTagHT, and GDCM_NAME_SPACE::ElementSet::TagHT.

Referenced by ComputeGroup0002Length(), and GDCM_NAME_SPACE::Validator::SetInput().

00171 {
00172    gdcmAssertMacro (ItTagHT != TagHT.end());
00173 
00174    ++ItTagHT;
00175    if (ItTagHT != TagHT.end())
00176       return  ItTagHT->second;
00177    return NULL;
00178 }

int GDCM_NAME_SPACE::Base::GetPrintLevel  )  [inline, inherited]
 

Gets the print level for the Dicom Entries.

Definition at line 50 of file gdcmBase.h.

00050 { return PrintLevel; }

Dict * GDCM_NAME_SPACE::Document::GetPubDict  ) 
 

Get the public dictionary used.

Definition at line 314 of file gdcmDocument.cxx.

References RefPubDict.

00315 {
00316    return RefPubDict;
00317 }

const unsigned long& GDCM_NAME_SPACE::RefCounter::GetRefCount  )  const [inline, inherited]
 

Get the reference counting.

Returns:
Reference count

Definition at line 59 of file gdcmRefCounter.h.

00060    {
00061       return RefCount;
00062    }

SeqEntry * GDCM_NAME_SPACE::DocEntrySet::GetSeqEntry uint16_t  group,
uint16_t  elem
[inherited]
 

Same as Document::GetDocEntry except it returns a result only when the corresponding entry is of type SeqEntry.

Parameters:
group Group number of the searched Dicom Element
elem Element number of the searched Dicom Element
Returns:
When present, the corresponding SeqEntry.

Definition at line 119 of file gdcmDocEntrySet.cxx.

References GDCM_NAME_SPACE::DocEntrySet::GetDocEntry().

Referenced by DoTheLoadingDocumentJob(), GDCM_NAME_SPACE::File::GetRescaleSlopeIntercept(), and GDCM_NAME_SPACE::File::GetSpacing().

00120 {
00121    DocEntry *currentEntry = GetDocEntry(group, elem);
00122    if ( !currentEntry )
00123       return NULL;
00124 
00125    return dynamic_cast<SeqEntry*>(currentEntry);
00126 }

Dict * GDCM_NAME_SPACE::Document::GetShaDict  ) 
 

Get the shadow dictionary used.

Definition at line 322 of file gdcmDocument.cxx.

References RefShaDict.

00323 {
00324    return RefShaDict;
00325 }

int GDCM_NAME_SPACE::Document::GetSwapCode  )  [inline]
 

'Swap code' accessor (see SwapCode )

Definition at line 74 of file gdcmDocument.h.

Referenced by GDCM_NAME_SPACE::PixelReadConvert::GrabInformationsFromFile().

00074 { return SwapCode; }

std::string GDCM_NAME_SPACE::Document::GetTransferSyntax  ) 
 

Accessor to the Transfer Syntax (when present) of the current document (it internally handles reading the value from disk when only parsing occured).

Returns:
The encountered Transfer Syntax of the current document, if DICOM. GDCM_UNKNOWN for ACR-NEMA files (or broken headers ...)

Definition at line 429 of file gdcmDocument.cxx.

References GDCM_NAME_SPACE::GDCM_UNKNOWN, gdcmWarningMacro, and GDCM_NAME_SPACE::ElementSet::GetDocEntry().

Referenced by GDCM_NAME_SPACE::File::ComputeJPEGFragmentInfo(), GDCM_NAME_SPACE::File::ComputeRLEInfo(), GDCM_NAME_SPACE::File::DoTheLoadingJob(), and HandleOutOfGroup0002().

00430 {
00431    DocEntry *entry = GetDocEntry(0x0002, 0x0010);
00432    if ( !entry )
00433    {
00434       return GDCM_UNKNOWN;
00435    }
00436 
00437    // The entry might be present but not loaded (parsing and loading
00438    // happen at different stages): try loading and proceed with check...
00439    
00440    // Well ...
00441    // (parsing and loading happen at the very same stage!) 
00442    //LoadDocEntrySafe(entry); //JPRx
00443    if (DataEntry *dataEntry = dynamic_cast<DataEntry *>(entry) )
00444    {
00445       std::string transfer = dataEntry->GetString();
00446       // The actual transfer (as read from disk) might be padded. We
00447       // first need to remove the potential padding. We can make the
00448       // weak assumption that padding was not executed with digits...
00449       if  ( transfer.length() == 0 )
00450       {
00451          // for brain damaged headers
00452          gdcmWarningMacro( "Transfer Syntax has length = 0.");
00453          return GDCM_UNKNOWN;
00454       }
00455       while ( !isdigit((unsigned char)transfer[transfer.length()-1]) )
00456       {
00457          transfer.erase(transfer.length()-1, 1);
00458          if  ( transfer.length() == 0 )
00459          {
00460             // for brain damaged headers
00461             gdcmWarningMacro( "Transfer Syntax contains no valid character.");
00462             return GDCM_UNKNOWN;
00463          }
00464       }
00465       return transfer;
00466    }
00467    return GDCM_UNKNOWN;
00468 }

std::string GDCM_NAME_SPACE::Document::GetTransferSyntaxName  ) 
 

Accesses the info from 0002,0010 : Transfer Syntax and TS.

Returns:
The full Transfer Syntax Name (as opposed to Transfer Syntax UID)

Definition at line 474 of file gdcmDocument.cxx.

References GDCM_NAME_SPACE::GDCM_NOTLOADED, GDCM_NAME_SPACE::GDCM_UNFOUND, gdcmDebugMacro, gdcmErrorMacro, GDCM_NAME_SPACE::DocEntrySet::GetEntryString(), and GDCM_NAME_SPACE::Global::GetTS().

Referenced by HandleOutOfGroup0002().

00475 {
00476    // use the TS (TS : Transfer Syntax)
00477    std::string transferSyntax = GetEntryString(0x0002,0x0010);
00478 
00479    if ( (transferSyntax.find(GDCM_NOTLOADED) < transferSyntax.length()) )
00480    {
00481       gdcmErrorMacro( "Transfer Syntax not loaded. " << std::endl
00482                << "Better you increase MAX_SIZE_LOAD_ELEMENT_VALUE" );
00483       return "Uncompressed ACR-NEMA";
00484    }
00485    if ( transferSyntax == GDCM_UNFOUND )
00486    {
00487       gdcmDebugMacro( "Unfound Transfer Syntax (0002,0010)");
00488       return "Uncompressed ACR-NEMA";
00489    }
00490 
00491    // we do it only when we need it
00492    const TSKey &tsName = Global::GetTS()->GetValue( transferSyntax );
00493 
00494    // Global::GetTS() is a global static you shall never try to delete it!
00495    return tsName;
00496 }

void GDCM_NAME_SPACE::Document::HandleBrokenEndian uint16_t &  group,
uint16_t &  elem
[private]
 

Handle broken private tag from Philips NTSCAN where the endianess is being switched to BigEndian for no apparent reason.

Returns:
no return

Definition at line 2349 of file gdcmDocument.cxx.

References gdcmDebugMacro, gdcmWarningMacro, and SwitchByteSwapCode().

Referenced by ReadNextDocEntry().

02350 {
02351  // for strange PMS Gyroscan Intera images
02352  // Item 'starter' has a tag : 0x3f3f,0x3f00, for no apparent reason
02353  
02354  // --- Feel free to remove this test *on your own coy of gdcm*
02355  //     if you are sure you'll never face this problem.
02356  
02357    if ((group == 0x3f3f) && (elem == 0x3f00))
02358    {
02359      // start endian swap mark for group found
02360      gdcmDebugMacro( " delimiter 0x3f3f  found." );
02361      // fix the tag
02362      group = 0xfffe;
02363      elem  = 0xe000;
02364      return;
02365    }
02366    // --- End of removable code
02367    
02368    // Endian reversion. 
02369    // Some files contain groups of tags with reversed endianess.
02370    static int reversedEndian = 0;
02371    // try to fix endian switching in the middle of headers
02372    if ((group == 0xfeff) && (elem == 0x00e0))
02373    {
02374      // start endian swap mark for group found
02375      gdcmDebugMacro( "Start endian swap mark found." );
02376      reversedEndian++;
02377      SwitchByteSwapCode();
02378      // fix the tag
02379      group = 0xfffe;
02380      elem  = 0xe000;
02381    } 
02382    else if (group == 0xfffe && elem == 0xe00d && reversedEndian) 
02383    {
02384      // end of reversed endian group
02385      gdcmDebugMacro( "End of reversed endian." );
02386      reversedEndian--;
02387      SwitchByteSwapCode();
02388    }
02389    else if (group == 0xfeff && elem == 0xdde0) 
02390    {
02391      // reversed Sequence Terminator found
02392      // probabely a bug in the header !
02393      // Do what you want, it breaks !
02394      //reversedEndian--;
02395      //SwitchByteSwapCode();
02396      gdcmWarningMacro( "Should never get here! reversed Sequence Terminator!" );
02397      // fix the tag
02398       group = 0xfffe;
02399       elem  = 0xe0dd;  
02400    }
02401    else if (group == 0xfffe && elem == 0xe0dd) 
02402    {
02403       gdcmDebugMacro( "Straight Sequence Terminator." );  
02404    }
02405 }

void GDCM_NAME_SPACE::Document::HandleOutOfGroup0002 uint16_t &  group,
uint16_t &  elem
[private]
 

Group 0002 is always coded Little Endian whatever Transfer Syntax is.

Returns:
no return
Todo:
find a trick to warn user and stop processing

Definition at line 2412 of file gdcmDocument.cxx.

References Filetype, GDCM_NAME_SPACE::GDCM_UNKNOWN, gdcmDebugMacro, gdcmWarningMacro, GetTransferSyntax(), GetTransferSyntaxName(), GDCM_NAME_SPACE::Global::GetTS(), Group0002Parsed, GDCM_NAME_SPACE::ImplicitVR, SwapShort(), and SwitchByteSwapCode().

Referenced by ReadNextDocEntry().

02413 {
02414    // Endian reversion. 
02415    // Some files contain groups of tags with reversed endianess.
02416    
02417       Group0002Parsed = true;
02418       // we just came out of group 0002
02419       // if Transfer Syntax is Big Endian we have to change CheckSwap
02420 
02421       std::string ts = GetTransferSyntax();
02422       TS::SpecialType s = Global::GetTS()->GetSpecialTransferSyntax(ts);
02423 
02424       // Group 0002 is always 'Explicit ...' 
02425       // even when Transfer Syntax says 'Implicit ..." 
02426 
02427       if ( s == TS::ImplicitVRLittleEndian 
02428         ||
02429           s == TS::ImplicitVRBigEndianPrivateGE  
02430          )
02431       {
02432          Filetype = ImplicitVR;
02433       }
02434        
02435       // FIXME Strangely, this works with 
02436       //'Implicit VR BigEndian Transfer Syntax' (GE Private)
02437       //
02438       // --> Probabely normal, since we considered we never have 
02439       // to trust manufacturers.
02440       // (we often find 'Implicit VR' tag, 
02441       // even when Transfer Syntax tells us it's Explicit ...
02442       
02443        // NEVER trust the meta elements!
02444        // (see what ezDICOM does ...)
02445              
02446       /*
02447       if ( s ==  TS::ExplicitVRBigEndian )
02448       {
02449          gdcmDebugMacro("Transfer Syntax Name = [" 
02450                         << GetTransferSyntaxName() << "]" );
02451          SwitchByteSwapCode();
02452          group = SwapShort(group);
02453          elem  = SwapShort(elem);
02454       }
02455       */
02456     //-- Broken ACR  may start with a Shadow Group --
02457     // worse : some ACR-NEMA like files start 00028 group ?!? 
02458     if ( !( (group >= 0x0001 && group <= 0x0008) || group == 0x0028 ) )
02459     {
02460        // We trust what we see.
02461        SwitchByteSwapCode();
02462        group = SwapShort(group);
02463        elem  = SwapShort(elem); 
02464        // not what we where told (by meta elements) !
02465        gdcmDebugMacro("Transfer Syntax Name = ["       
02466                        << GetTransferSyntaxName() << "]" );         
02467     }
02468       
02470             
02471       if ( s == TS::DeflatedExplicitVRLittleEndian)
02472       {
02473            gdcmWarningMacro("Transfer Syntax [" 
02474                         << GetTransferSyntaxName() << "] :"
02475                         << " not yet dealt with ");
02476            return;       
02477       }
02478       
02479       // The following shouldn't occur very often
02480       // Let's check at the very end.
02481 
02482       if ( ts == GDCM_UNKNOWN )
02483       {
02484          gdcmDebugMacro("True DICOM File, with NO Transfer Syntax (?!) " );
02485          return;      
02486       }
02487       
02488       if ( !Global::GetTS()->IsTransferSyntax(ts) )
02489       {
02490          gdcmWarningMacro("True DICOM File, with illegal Transfer Syntax: [" 
02491                           << ts << "]");
02492          return;
02493       }      
02494 }

void GDCM_NAME_SPACE::Document::Initialize  )  [private]
 

Loads all the needed Dictionaries.

Warning:
NOT end user intended method !

Reimplemented in GDCM_NAME_SPACE::DicomDir.

Definition at line 1086 of file gdcmDocument.cxx.

References Filetype, GDCM_NAME_SPACE::DictSet::GetDefaultPubDict(), GDCM_NAME_SPACE::Global::GetDicts(), RefPubDict, RefShaDict, and GDCM_NAME_SPACE::Unknown.

Referenced by Document().

01087 {
01088    RefPubDict = Global::GetDicts()->GetDefaultPubDict();
01089    RefShaDict = NULL;
01090    Filetype   = Unknown;
01091 }

DataEntry * GDCM_NAME_SPACE::DocEntrySet::InsertEntryBinArea uint8_t *  binArea,
int  lgth,
uint16_t  group,
uint16_t  elem,
VRKey const &  vr = GDCM_VRUNKNOWN
[inherited]
 

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.

Parameters:
binArea (binary) value to be set
lgth length of the Bin Area we want to set
group Group number of the Entry
elem Element number of the Entry
vr V(alue) R(epresentation) of the Entry -if private Entry-
Returns:
pointer to the modified/created Header Entry (NULL when creation failed).

Definition at line 290 of file gdcmDocEntrySet.cxx.

References GDCM_NAME_SPACE::DocEntrySet::AddEntry(), GDCM_NAME_SPACE::RefCounter::Delete(), gdcmWarningMacro, GDCM_NAME_SPACE::DocEntrySet::GetDocEntry(), GDCM_NAME_SPACE::DocEntry::GetVR(), GDCM_NAME_SPACE::DocEntrySet::NewDataEntry(), GDCM_NAME_SPACE::DocEntrySet::RemoveEntry(), and GDCM_NAME_SPACE::DocEntrySet::SetEntryBinArea().

Referenced by GDCM_NAME_SPACE::FileHelper::InsertEntryBinArea().

00293 {
00294    DataEntry *dataEntry = 0;
00295    DocEntry *currentEntry = GetDocEntry( group, elem );
00296 
00297    // Verify the currentEntry
00298    if (currentEntry)
00299    {
00300       dataEntry = dynamic_cast<DataEntry *>(currentEntry);
00301 
00302       // Verify the VR
00303       if ( dataEntry )
00304          if ( dataEntry->GetVR()!=vr )
00305             dataEntry = NULL;
00306 
00307       // if currentEntry doesn't correspond to the requested dataEntry
00308       if ( !dataEntry)
00309       {
00310          if ( !RemoveEntry(currentEntry) )
00311          {
00312             gdcmWarningMacro( "Removal of previous DocEntry failed.");
00313             return NULL;
00314          }
00315       }
00316    }
00317 
00318    // Create a new dataEntry if necessary
00319    if ( !dataEntry)
00320    {
00321       dataEntry = NewDataEntry(group, elem, vr);
00322 
00323       if ( !AddEntry(dataEntry) )
00324       {
00325          gdcmWarningMacro( "AddEntry failed although this is a creation.");
00326          dataEntry->Delete();
00327          return NULL;
00328       }
00329       dataEntry->Delete();
00330    }
00331 
00332    // Set the dataEntry value
00333    uint8_t *tmpArea;
00334    if ( lgth>0 && binArea )
00335    {
00336       tmpArea = new uint8_t[lgth];
00337       memcpy(tmpArea,binArea,lgth);
00338    }
00339    else
00340    {
00341       tmpArea = 0;
00342    }
00343    if ( !SetEntryBinArea(tmpArea,lgth,dataEntry) )
00344    {
00345       if ( tmpArea )
00346       {
00347          delete[] tmpArea;
00348       }
00349    }
00350    return dataEntry;
00351 }  

DataEntry * GDCM_NAME_SPACE::DocEntrySet::InsertEntryString std::string const &  value,
uint16_t  group,
uint16_t  elem,
VRKey const &  vr = GDCM_VRUNKNOWN
[inherited]
 

Modifies the value of a given Doc Entry (Dicom Element) when it exists. Creates it with the given value when unexistant.

Parameters:
value (string) Value to be set
group Group number of the Entry
elem Element number of the Entry
vr V(alue) R(epresentation) of the Entry -if private Entry-
Returns:
pointer to the modified/created Header Entry (NULL when creation failed).

Definition at line 216 of file gdcmDocEntrySet.cxx.

References GDCM_NAME_SPACE::DocEntrySet::AddEntry(), GDCM_NAME_SPACE::RefCounter::Delete(), GDCM_NAME_SPACE::GDCM_VRUNKNOWN, gdcmWarningMacro, GDCM_NAME_SPACE::DictSet::GetDefaultPubDict(), GDCM_NAME_SPACE::Global::GetDicts(), GDCM_NAME_SPACE::DocEntrySet::GetDocEntry(), GDCM_NAME_SPACE::Dict::GetEntry(), GDCM_NAME_SPACE::DocEntry::GetKey(), GDCM_NAME_SPACE::DictEntry::GetVR(), GDCM_NAME_SPACE::DocEntry::GetVR(), GDCM_NAME_SPACE::DocEntrySet::NewDataEntry(), GDCM_NAME_SPACE::RefCounter::Register(), GDCM_NAME_SPACE::DocEntrySet::RemoveEntry(), and GDCM_NAME_SPACE::DocEntrySet::SetEntryString().

Referenced by GDCM_NAME_SPACE::FileHelper::InsertEntryString(), GDCM_NAME_SPACE::FileHelper::Write(), and GDCM_NAME_SPACE::File::Write().

00219 {
00220    DataEntry *dataEntry = 0;
00221    DocEntry *currentEntry = GetDocEntry( group, elem );
00222    VRKey localVR = vr;
00223    if (currentEntry)
00224    {
00225       dataEntry = dynamic_cast<DataEntry *>(currentEntry);
00226 
00227       // Verify the VR
00228       if ( dataEntry )
00229          if ( dataEntry->GetVR()!=vr )
00230             dataEntry = NULL;
00231 
00232       // if currentEntry doesn't correspond to the requested dataEntry
00233       if ( !dataEntry)
00234       {
00235          if ( !RemoveEntry(currentEntry) )
00236          {
00237             gdcmWarningMacro( "Removal of previous DocEntry failed.");
00238             return NULL;
00239          }
00240       }
00241    }
00242   
00243    else // the 'currentEntry' was not found
00244    {
00245       if ( vr == GDCM_VRUNKNOWN ) // user didn't specify a VR.
00246                                   //  Probabely he trusts the Dicom Dict !
00247       {
00248           DictEntry *e = 
00249             Global::GetDicts()->GetDefaultPubDict()->GetEntry(group, elem);
00250           if ( e )
00251           {
00252              localVR = e->GetVR();  
00253              e->Register(); // ?? JPRx
00254          }
00255       }
00256    }
00257 
00258    // Create a new dataEntry if necessary
00259    if ( !dataEntry )
00260    {
00261       dataEntry = NewDataEntry( group, elem, localVR );
00262 
00263       if ( !AddEntry(dataEntry) )
00264       {
00265          gdcmWarningMacro("AddEntry " << dataEntry->GetKey() 
00266                  << " failed although this is a creation.");
00267          dataEntry->Delete();
00268          return NULL;
00269       }
00270       dataEntry->Delete(); // ?!? JPRx
00271    }
00272 
00273    // Set the dataEntry value
00274    SetEntryString(value, dataEntry); // The std::string value
00275    return dataEntry;
00276 }

SeqEntry * GDCM_NAME_SPACE::DocEntrySet::InsertSeqEntry uint16_t  group,
uint16_t  elem
[inherited]
 

Creates a new gdcm::SeqEntry and adds it to the current DocEntrySet. (remove any existing entry with same group,elem).

Parameters:
group Group number of the Entry
elem Element number of the Entry
Returns:
pointer to the created SeqEntry (NULL when creation failed).

Definition at line 361 of file gdcmDocEntrySet.cxx.

References GDCM_NAME_SPACE::DocEntrySet::AddEntry(), GDCM_NAME_SPACE::RefCounter::Delete(), gdcmWarningMacro, GDCM_NAME_SPACE::DocEntrySet::GetDocEntry(), GDCM_NAME_SPACE::DocEntrySet::NewSeqEntry(), and GDCM_NAME_SPACE::DocEntrySet::RemoveEntry().

Referenced by GDCM_NAME_SPACE::FileHelper::InsertSeqEntry().

00362 {
00363    SeqEntry *seqEntry = 0;
00364    DocEntry *currentEntry = GetDocEntry( group, elem );
00365 
00366    // Verify the currentEntry
00367    if ( currentEntry )
00368    {
00369       seqEntry = dynamic_cast<SeqEntry *>(currentEntry);
00370 
00371       // Verify the VR
00372       if ( seqEntry )
00373          seqEntry = NULL;
00374 
00375       // if currentEntry doesn't correspond to the requested seqEntry
00376       if ( !seqEntry )
00377       {
00378          if (!RemoveEntry(currentEntry))
00379          {
00380             gdcmWarningMacro( "Removal of previous DocEntry failed for ("
00381                <<std::hex << group << "|" << elem <<")" );
00382             return NULL;
00383          }
00384       }
00385    }
00386    // Create a new seqEntry if necessary
00387    if ( !seqEntry )
00388    {
00389       seqEntry = NewSeqEntry(group, elem);
00390 
00391       if ( !AddEntry(seqEntry) )
00392       {
00393          gdcmWarningMacro( "AddEntry failed although this is a creation for ("
00394             <<std::hex << group << "|" << elem <<")" );
00395          seqEntry->Delete();
00396          return NULL;
00397       }
00398       seqEntry->Delete();
00399    }
00400    // Remark :
00401    // SequenceDelimitationItem will be added at the end of the SeqEntry,
00402    // at write time
00403    return seqEntry;
00404 } 

bool GDCM_NAME_SPACE::Document::IsDicomV3  ) 
 

Predicate for dicom version 3 file.

Returns:
True when the file is a dicom version 3.

Definition at line 386 of file gdcmDocument.cxx.

References GDCM_NAME_SPACE::ElementSet::GetDocEntry().

Referenced by GDCM_NAME_SPACE::File::GetYSize(), and GDCM_NAME_SPACE::PixelReadConvert::GrabInformationsFromFile().

00387 {
00388    // Checking if Transfer Syntax exists is enough
00389    // Anyway, it's too late check if the 'Preamble' was found ...
00390    // And ... would it be a rich idea to check ?
00391    // (some 'no Preamble' DICOM images exist !)
00392    return GetDocEntry(0x0002, 0x0010) != NULL;
00393 }

bool GDCM_NAME_SPACE::Document::IsDocEntryAnInteger DocEntry entry  )  [private]
 

Apply some heuristics to predict whether the considered element value contains/represents an integer or not.

Parameters:
entry The element value on which to apply the predicate.
Returns:
The result of the heuristical predicate.

Definition at line 1863 of file gdcmDocument.cxx.

References gdcmWarningMacro, GDCM_NAME_SPACE::DocEntry::GetElement(), GDCM_NAME_SPACE::DocEntry::GetGroup(), GDCM_NAME_SPACE::DocEntry::GetLength(), and GDCM_NAME_SPACE::DocEntry::GetVR().

01864 {
01865    uint16_t elem         = entry->GetElement();
01866    uint16_t group        = entry->GetGroup();
01867    const VRKey &vr       = entry->GetVR();
01868    uint32_t length       = entry->GetLength();
01869 
01870    // When we have some semantics on the element we just read, and if we
01871    // a priori know we are dealing with an integer, then we shall be
01872    // able to swap its element value properly.
01873    if ( elem == 0 )  // This is the group length of the group
01874    {  
01875       if ( length == 4 )
01876       {
01877          return true;
01878       }
01879       else 
01880       {
01881          // Although this should never happen, still some images have a
01882          // corrupted group length [e.g. have a glance at offset x(8336) of
01883          // gdcmData/gdcm-MR-PHILIPS-16-Multi-Seq.dcm.
01884          // Since for dicom compliant and well behaved headers, the present
01885          // test is useless (and might even look a bit paranoid), when we
01886          // encounter such an ill-formed image, we simply display a warning
01887          // message and proceed on parsing (while crossing fingers).
01888          long filePosition = Fp->tellg(); // Only when elem 0x0000 length is not 4 (?!?)
01889          (void)filePosition;
01890          gdcmWarningMacro( "Erroneous Group Length element length  on : (" 
01891            << std::hex << group << " , " << elem
01892            << ") -before- position x(" << filePosition << ")"
01893            << "lgt : " << length );
01894       }
01895    }
01896 
01897    if ( vr == "UL" || vr == "US" || vr == "SL" || vr == "SS" )
01898    {
01899       return true;
01900    }   
01901    return false;
01902 }

bool GDCM_NAME_SPACE::ElementSet::IsEmpty  )  [inline, virtual, inherited]
 

Tells us if the ElementSet contains no entry.

Implements GDCM_NAME_SPACE::DocEntrySet.

Definition at line 59 of file gdcmElementSet.h.

Referenced by DoTheLoadingDocumentJob(), and IsParsable().

00059 { return TagHT.empty(); }

bool GDCM_NAME_SPACE::Document::IsPapyrus  ) 
 

Predicate for Papyrus file Dedicated to whomsoever it may concern.

Returns:
True when the file is a Papyrus file.

Definition at line 400 of file gdcmDocument.cxx.

References GDCM_NAME_SPACE::ElementSet::GetDocEntry().

00401 {
00402    // check for Papyrus private Sequence
00403    DocEntry *e = GetDocEntry(0x0041, 0x1050);
00404    if ( !e )
00405       return false;
00406    // check if it's actually a Sequence
00407    if ( !dynamic_cast<SeqEntry*>(e) )
00408       return  false;
00409    return true;
00410 }

bool GDCM_NAME_SPACE::Document::IsParsable  ) 
 

This predicate tells us whether or not the current Document was properly parsed and contains at least *one* Dicom Element (and nothing more, sorry).

Returns:
false when we're 150 % sure it's NOT a Dicom/Acr file, true otherwise.

Definition at line 354 of file gdcmDocument.cxx.

References Filetype, gdcmWarningMacro, GetFileName(), GDCM_NAME_SPACE::ElementSet::IsEmpty(), and GDCM_NAME_SPACE::Unknown.

Referenced by IsReadable().

00355 {
00356    if ( Filetype == Unknown )
00357    {
00358       gdcmWarningMacro( "Wrong filetype for " << GetFileName());
00359       return false;
00360    }
00361 
00362    if ( IsEmpty() )
00363    { 
00364       gdcmWarningMacro( "No tag in internal hash table.");
00365       return false;
00366    }
00367 
00368    return true;
00369 }

bool GDCM_NAME_SPACE::Document::IsReadable  )  [virtual]
 

This predicate tells us whether or not the current Document was properly parsed and contains at least *one* Dicom Element (and nothing more, sorry).

Returns:
false when we're 150 % sure it's NOT a Dicom/Acr file, true otherwise.

Reimplemented in GDCM_NAME_SPACE::DicomDir, and GDCM_NAME_SPACE::File.

Definition at line 377 of file gdcmDocument.cxx.

References IsParsable().

Referenced by GDCM_NAME_SPACE::File::IsReadable().

00378 {
00379    return IsParsable();
00380 }

int GDCM_NAME_SPACE::ElementSet::IsVRCoherent uint16_t  group  )  [inherited]
 

Checks whether *all* the DataEntries of the group have all the same type for VR (ImplicitVR or ExplicitVR).

Parameters:
group group number to be checked
Returns:
1:ImplicitVR 2:ExplicitVR -1:NotCoherent

Definition at line 225 of file gdcmElementSet.cxx.

References GDCM_NAME_SPACE::ElementSet::TagHT.

00226 {
00227    uint16_t currentGroup;
00228    int codeVR = -1;
00229    int currentCodeVR;
00230    for(TagDocEntryHT::iterator cc = TagHT.begin();cc != TagHT.end(); ++cc)
00231    {
00232       currentGroup = cc->second->GetGroup();
00233 
00234       if ( currentGroup < group )
00235          continue;   
00236       if ( currentGroup > group )
00237          break;
00238       // currentGroup == group
00239       if (codeVR == -1)
00240       {
00241          if (cc->second->IsImplicitVR() )
00242             codeVR = 1;
00243          else 
00244             codeVR = 2;
00245          continue;
00246       }
00247       else
00248       {
00249          if (cc->second->IsImplicitVR() )
00250             currentCodeVR = 1; //Implicit
00251          else 
00252             currentCodeVR = 2; // Explicit  
00253   
00254          if ( currentCodeVR == codeVR )
00255            continue;
00256          else
00257             return -1;    // -1 : not coherent 
00258       }
00259    }   
00260    return codeVR;
00261 }

bool GDCM_NAME_SPACE::Document::Load  )  [virtual]
 

Loader. use SetLoadMode(), SetFileName() before !

Returns:
false if file cannot be open or no swap info was found, or no tag was found.

Reimplemented in GDCM_NAME_SPACE::DicomDir, and GDCM_NAME_SPACE::File.

Definition at line 92 of file gdcmDocument.cxx.

References DoTheLoadingDocumentJob(), gdcmWarningMacro, and GetFileName().

Referenced by GDCM_NAME_SPACE::DicomDir::DoTheLoadingJob().

00093 {
00094    if ( GetFileName() == "" )
00095    {
00096       gdcmWarningMacro( "Use SetFileName, before !" );
00097       return false;
00098    }
00099    return DoTheLoadingDocumentJob( );
00100 }

void GDCM_NAME_SPACE::Document::LoadDocEntry DocEntry entry,
bool  forceLoad = false
[private]
 

Loads (or not) the element content depending if its length exceeds or not the value specified with Document::SetMaxSizeLoadEntry().

Parameters:
entry Header Entry (Dicom Element) to be dealt with
forceLoad whether you want to force loading of 'long' elements
Todo:
: a method that *doesn't* load anything (maybe with MaxSizeLoadEntry=0 ?) + a ForceLoad call on the +/- 20 'usefull' fields Allow user to tell the fields he wants to ForceLoad during initial stage. Later, a GetString or GetBinArea will load the value from disk, if not loaded + a method that load *everything* that's not yet loaded

Definition at line 1442 of file gdcmDocument.cxx.

References GDCM_NAME_SPACE::DocEntry::GetElement(), GDCM_NAME_SPACE::DocEntry::GetGroup(), GDCM_NAME_SPACE::DocEntry::GetLength(), GDCM_NAME_SPACE::DocEntry::GetVR(), LoadEntryBinArea(), MaxSizeLoadEntry, GDCM_NAME_SPACE::DataEntry::SetBinArea(), GDCM_NAME_SPACE::DataEntry::SetState(), and GDCM_NAME_SPACE::DataEntry::STATE_NOTLOADED.

01443 {
01444    uint16_t group   = entry->GetGroup();
01445    uint16_t elem    = entry->GetElement();
01446    const VRKey  &vr = entry->GetVR();
01447    uint32_t length  = entry->GetLength();
01448 
01449  //  Fp->seekg((long)entry->GetOffset(), std::ios::beg); // JPRx
01450 
01451    // A SeQuence "contains" a set of Elements.  
01452    //          (fffe e000) tells us an Element is beginning
01453    //          (fffe e00d) tells us an Element just ended
01454    //          (fffe e0dd) tells us the current SeQuence just ended
01455    //          (fffe 0000) is an 'impossible' tag value, 
01456    //                                    found in MR-PHILIPS-16-Multi-Seq.dcm
01457    
01458    if ( (group == 0xfffe && elem != 0x0000 ) || vr == "SQ" )
01459    {
01460       // NO more value field for SQ !
01461       return;
01462    }
01463 
01464    DataEntry *dataEntryPtr = dynamic_cast< DataEntry* >(entry);
01465    if( !dataEntryPtr )
01466    {
01467       return;
01468    }
01469 
01470    // When the length is zero things are easy:
01471    if ( length == 0 )
01472    {
01473       dataEntryPtr->SetBinArea(NULL,true);
01474       return;
01475    }
01476 
01477    // The elements whose length is bigger than the specified upper bound
01478    // are not loaded.
01479 
01480    if (!forceLoad)
01481    {
01482       if (length > MaxSizeLoadEntry)
01483       {
01484          dataEntryPtr->SetBinArea(NULL,true);
01485          dataEntryPtr->SetState(DataEntry::STATE_NOTLOADED);
01486 
01487        // to be sure we are at the end of the value ...
01488        //  Fp->seekg((long)entry->GetOffset()+(long)entry->GetLength(),
01489        //           std::ios::beg);  //JPRx
01490          return;
01491       }
01492    }
01493    
01500    
01501    LoadEntryBinArea(dataEntryPtr); // last one, not to erase length !
01502 }

void GDCM_NAME_SPACE::Document::LoadEntryBinArea DataEntry entry  )  [virtual]
 

Loads (from disk) the element content when a string is not suitable.

Parameters:
entry Entry whose binArea is going to be loaded

Definition at line 761 of file gdcmDocument.cxx.

References gdcmWarningMacro, GDCM_NAME_SPACE::DataEntry::GetBinArea(), GDCM_NAME_SPACE::DocEntry::GetElement(), GDCM_NAME_SPACE::DocEntry::GetGroup(), GDCM_NAME_SPACE::DocEntry::GetLength(), GDCM_NAME_SPACE::DocEntry::GetOffset(), OpenFile(), GDCM_NAME_SPACE::DataEntry::SetState(), and GDCM_NAME_SPACE::DataEntry::STATE_UNREAD.

00762 { 
00763    if( entry->GetBinArea() )
00764       return;
00765 
00766    bool openFile = !Fp;
00767    if ( openFile )
00768       OpenFile();
00769 
00770    //size_t o =(size_t)entry->GetOffset();
00771    Fp->seekg((size_t)entry->GetOffset(), std::ios::beg);  // FIXME : for each DataEntry !
00772 
00773    size_t l = entry->GetLength();
00774    uint8_t *data = new uint8_t[l];
00775    if ( !data )
00776    {
00777       gdcmWarningMacro(  "Cannot allocate DataEntry content for : "
00778                        << std::hex << entry->GetGroup() 
00779                        << "|" << entry->GetElement() );
00780       return;
00781    }
00782 
00783    // Read the data
00784    Fp->read((char*)data, l);
00785    if ( Fp->fail() || Fp->eof() )
00786    {
00787       delete[] data;
00788       entry->SetState(DataEntry::STATE_UNREAD);
00789       return;
00790    }
00791 
00792    // Swap the data content if necessary
00793    uint32_t i;
00794    unsigned short vrLgth = 
00795                         Global::GetVR()->GetAtomicElementLength(entry->GetVR());
00796 
00797 // FIXME : trouble expected if we read an ... OW Entry (LUT, etc ..)
00798 //   if( entry->GetVR() == "OW" )
00799 //      vrLgth = 1;
00800 
00801    switch(vrLgth)
00802    {
00803       case 1:
00804       {
00805          break;
00806       }     
00807       case 2:
00808       {
00809          uint16_t *data16 = (uint16_t *)data;
00810          for(i=0;i<l/vrLgth;i++)
00811             data16[i] = SwapShort(data16[i]);
00812          break;
00813       }
00814       case 4:
00815       {
00816          uint32_t *data32 = (uint32_t *)data;
00817          for(i=0;i<l/vrLgth;i++)
00818             data32[i] = SwapLong(data32[i]);
00819          break;
00820       }
00821       case 8:
00822       {
00823          double *data64 = (double *)data;
00824          for(i=0;i<l/vrLgth;i++)
00825             data64[i] = SwapDouble(data64[i]);
00826          break;
00827       }
00828    }
00829    
00830    entry->SetBinArea(data);
00831 
00832    if ( openFile ) // The file is left in the state (open/close) it was at entrance
00833       CloseFile();
00834 }

void GDCM_NAME_SPACE::Document::LoadEntryBinArea uint16_t  group,
uint16_t  elem
[virtual]
 

Loads (from disk) the element content when a string is not suitable.

Parameters:
group group number of the Entry
elem element number of the Entry

Definition at line 736 of file gdcmDocument.cxx.

References gdcmDebugMacro, gdcmWarningMacro, and GDCM_NAME_SPACE::ElementSet::GetDocEntry().

Referenced by DoTheLoadingDocumentJob(), and LoadDocEntry().

00737 {
00738    // Search the corresponding DocEntry
00739    DocEntry *docEntry = GetDocEntry(group, elem);
00740    if ( !docEntry )
00741    {
00742       gdcmDebugMacro(std::hex << group << "|" << elem 
00743                        <<  " doesn't exist" );
00744       return;
00745    }
00746    DataEntry *dataEntry = dynamic_cast<DataEntry *>(docEntry);
00747    if ( !dataEntry )
00748    {
00749       gdcmWarningMacro(std::hex << group << "|" << elem 
00750                        <<  " is NOT a DataEntry");
00751       return;
00752    }
00753    LoadEntryBinArea(dataEntry);
00754 }

bool GDCM_NAME_SPACE::ElementSet::MayIWrite uint16_t   )  [inline, protected, inherited]
 

Some group are illegal withing some Dicom Documents Only the Document knows it.

Reimplemented in GDCM_NAME_SPACE::File.

Definition at line 70 of file gdcmElementSet.h.

Referenced by GDCM_NAME_SPACE::ElementSet::WriteContent().

00071                  { return true; }

DataEntry * GDCM_NAME_SPACE::DocEntrySet::NewDataEntry uint16_t  group,
uint16_t  elem,
VRKey const &  vr = GDCM_VRUNKNOWN
[inherited]
 

Build a new DataEntry from all the low level arguments.

Parameters:
group Group number of the new Entry
elem Element number of the new Entry
vr V(alue) R(epresentation) of the new Entry
Remarks:
The user of this method must destroy the DataEntry when unused

Definition at line 425 of file gdcmDocEntrySet.cxx.

References gdcmWarningMacro, and GDCM_NAME_SPACE::DataEntry::New().

Referenced by GDCM_NAME_SPACE::FileHelper::CopyDataEntry(), GDCM_NAME_SPACE::DocEntrySet::InsertEntryBinArea(), GDCM_NAME_SPACE::DocEntrySet::InsertEntryString(), and ReadNextDocEntry().

00427 {
00428 
00429    DataEntry *newEntry = DataEntry::New(group, elem, vr);
00430    if (!newEntry) 
00431    {
00432       gdcmWarningMacro( "Failed to allocate DataEntry for ("
00433           <<std::hex << group << "|" << elem <<")" );
00434       return 0;
00435    }
00436    return newEntry;
00437 }

SeqEntry * GDCM_NAME_SPACE::DocEntrySet::NewSeqEntry uint16_t  group,
uint16_t  elem
[inherited]
 

Build a new SeqEntry from all the low level arguments.

Parameters:
group Group number of the new Entry
elem Element number of the new Entry
Remarks:
The user of this method must destroy the SeqEntry when unused

Definition at line 445 of file gdcmDocEntrySet.cxx.

References gdcmWarningMacro, and GDCM_NAME_SPACE::SeqEntry::New().

Referenced by Backtrack(), GDCM_NAME_SPACE::DocEntrySet::InsertSeqEntry(), and ReadNextDocEntry().

00446 {
00447    //DictEntry *dictEntry = GetDictEntry(group, elem, "SQ");
00448 
00449    //SeqEntry *newEntry = SeqEntry::New( dictEntry );
00450    SeqEntry *newEntry = SeqEntry::New( group, elem );
00451    //dictEntry->Unregister(); // GetDictEntry register it
00452    if (!newEntry)
00453    {
00454       gdcmWarningMacro( "Failed to allocate SeqEntry for ("
00455          <<std::hex << group << "|" << elem <<")" );
00456       return 0;
00457    }     
00458    return newEntry;
00459 }

std::ifstream * GDCM_NAME_SPACE::Document::OpenFile  ) 
 

Tries to open the file Document::Filename and checks the preamble when existing, or if the file starts with an ACR-NEMA look-like element.

Returns:
The FILE pointer on success, 0 on failure.

Definition at line 590 of file gdcmDocument.cxx.

References Filename, and HasDCMPreamble.

Referenced by DoTheLoadingDocumentJob(), GDCM_NAME_SPACE::File::DoTheLoadingJob(), GDCM_NAME_SPACE::FileHelper::GetRaw(), and LoadEntryBinArea().

00591 {
00592    HasDCMPreamble = false;
00593    if (Filename.length() == 0) 
00594    {
00595       return 0;
00596    }
00597 
00598    if ( Fp )
00599    {
00600       gdcmDebugMacro( "File already open: " << Filename.c_str());
00601       CloseFile();
00602    }
00603 
00604    Fp = new std::ifstream(Filename.c_str(), std::ios::in | std::ios::binary);
00605    if ( ! *Fp )
00606    {
00607    // Don't user gdcmErrorMacro :
00608    // a spurious message will appear when you use, for instance 
00609    // gdcm::FileHelper *fh = new gdcm::FileHelper( outputFileName );
00610    // to create outputFileName.
00611    
00612    // FIXME : if the upper comment is still usefull 
00613    //         --> the constructor is not so good ...
00614    
00615       gdcmWarningMacro( "Cannot open file: " << Filename.c_str());
00616       delete Fp;
00617       Fp = 0;
00618       return 0;
00619       //exit(1); // No function is allowed to leave the application instead
00620                  // of warning the caller
00621    }
00622  
00623    uint16_t zero = 0;
00624    Fp->read((char*)&zero, (size_t)2);
00625    if ( Fp->eof() )
00626    {
00627       CloseFile();
00628       return 0;
00629    }
00630  
00631    //-- DICOM --
00632    Fp->seekg(126L, std::ios::cur);  // Once per Document
00633    char dicm[4]; // = {' ',' ',' ',' '};
00634    Fp->read(dicm,  (size_t)4);
00635    if ( Fp->eof() )
00636    {
00637       CloseFile();
00638       return 0;
00639    }
00640    
00641    if ( memcmp(dicm, "DICM", 4) == 0 )
00642    {
00643       HasDCMPreamble = true;
00644       return Fp;
00645    }
00646 
00647    //-- Broken ACR or DICOM (?) with no Preamble; may start with a Shadow Group --
00648    // FIXME : We cannot be sure the preable is only zeroes..
00649    //         (see ACUSON-24-YBR_FULL-RLE.dcm )
00650    if ( 
00651        zero == 0x0001 || zero == 0x0100 || zero == 0x0002 || zero == 0x0200 ||
00652        zero == 0x0003 || zero == 0x0300 || zero == 0x0004 || zero == 0x0400 ||
00653        zero == 0x0005 || zero == 0x0500 || zero == 0x0006 || zero == 0x0600 ||
00654        zero == 0x0007 || zero == 0x0700 || zero == 0x0008 || zero == 0x0800 ||
00655        zero == 0x0028 || 0x2800    // worse : some ACR-NEMA like files 
00656                                    // start 00028 group ?!?      
00657        )
00658    {
00659       std::string msg = Util::Format(
00660         "ACR/DICOM starting by 0x(%04x) at the beginning of the file\n", zero);
00661       // FIXME : is it a Warning message, or a Debug message?
00662       gdcmWarningMacro( msg.c_str() );
00663       return Fp;
00664    }
00665    
00666    // -- Neither ACR/No Preamble Dicom nor DICOMV3 file
00667    CloseFile();
00668    // Don't user Warning nor Error, not to pollute the output
00669    // while directory recursive parsing ...
00670    gdcmDebugMacro( "Neither ACR/No Preamble Dicom nor DICOMV3 file: "
00671                       << Filename.c_str()); 
00672    return 0;
00673 }

bool GDCM_NAME_SPACE::Document::operator< Document document  ) 
 

Loads the element while preserving the current underlying file position indicator as opposed to LoadDocEntry that modifies it Compares two documents, according to DicomDir rules.

Warning:
Does NOT work with ACR-NEMA files
Todo:
Find a trick to solve the pb (use RET fields ?)
Parameters:
document to compare with current one
Returns:
true if 'smaller'

Definition at line 860 of file gdcmDocument.cxx.

References GDCM_NAME_SPACE::DocEntrySet::GetEntryString().

00861 {
00862    // Patient Name
00863    std::string s1 = GetEntryString(0x0010,0x0010);
00864    std::string s2 = document.GetEntryString(0x0010,0x0010);
00865    if (s1 < s2)
00866    {
00867       return true;
00868    }
00869    else if ( s1 > s2 )
00870    {
00871       return false;
00872    }
00873    else
00874    {
00875       // Patient ID
00876       s1 = GetEntryString(0x0010,0x0020);
00877       s2 = document.GetEntryString(0x0010,0x0020);
00878       if ( s1 < s2 )
00879       {
00880          return true;
00881       }
00882       else if ( s1 > s2 )
00883       {
00884          return false;
00885       }
00886       else
00887       {
00888          // Study Instance UID
00889          s1 = GetEntryString(0x0020,0x000d);
00890          s2 = document.GetEntryString(0x0020,0x000d);
00891          if ( s1 < s2 )
00892          {
00893             return true;
00894          }
00895          else if ( s1 > s2 )
00896          {
00897             return false;
00898          }
00899          else
00900          {
00901             // Serie Instance UID
00902             s1 = GetEntryString(0x0020,0x000e);
00903             s2 = document.GetEntryString(0x0020,0x000e);    
00904             if ( s1 < s2 )
00905             {
00906                return true;
00907             }
00908             else if ( s1 > s2 )
00909             {
00910                return false;
00911             }
00912          }
00913       }
00914    }
00915    return false;
00916 }

void GDCM_NAME_SPACE::Document::ParseDES DocEntrySet set,
long  offset,
long  l_max,
bool  delim_mode
[private]
 

Parses a DocEntrySet (Zero-level DocEntries or SQ Item DocEntries).

Parameters:
set DocEntrySet we are going to parse ('zero level' or a SQItem)
offset start of parsing
l_max length to parse (meaningless when we are in 'delimitor mode')
delim_mode : whether we are in 'delimitor mode' (l=0xffffff) or not
Todo:
FIXME : On 64 bits processors, tellg gives unexpected results after a while ? Probabely a bug in gdcm code somwhere (some memory erased ?)

Definition at line 1100 of file gdcmDocument.cxx.

References Backtrack(), gdcmDebugMacro, GDCM_NAME_SPACE::Debug::GetDebugFlag(), GDCM_NAME_SPACE::DocEntry::GetKey(), GDCM_NAME_SPACE::DocEntry::GetVR(), GDCM_NAME_SPACE::DocEntry::IsItemStarter(), and ReadNextDocEntry().

Referenced by DoTheLoadingDocumentJob().

01102 {
01103    DocEntry *newDocEntry;
01104    DataEntry *newDataEntry;
01105    SeqEntry *newSeqEntry;
01106    //VRKey vr;
01107    bool used; // will be set to false when something wrong happens to an Entry.
01108               // (Entry will then be deleted)
01109    bool delim_mode_intern = delim_mode;
01110    bool first = true;
01111    gdcmDebugMacro( "Enter in ParseDES, delim-mode " <<  delim_mode
01112                      << " at offset " << std::hex << "0x(" << offset << ")" );    
01113    while (true)
01114    {
01115    
01118 
01119 // Uncomment to track the bug
01120 /*   
01121    if( Debug::GetDebugFlag() )   
01122       std::cout << std::dec <<"(long)(Fp->tellg()) " << (long)(Fp->tellg()) // in Debug mode
01123                 << std::hex << " 0x(" <<(long)(Fp->tellg()) <<  ")" << std::endl;
01124  */ 
01125  
01126    // if ( !delim_mode && ((long)(Fp->tellg())-offset) >= l_max) // Once per DocEntry   
01127       if ( !delim_mode ) // 'and then' doesn't exist in C++ :-(
01128          if ( ((long)(Fp->tellg())-offset) >= l_max) // Once per DocEntry, when no delim mode
01129          {
01130             break;
01131          }
01132 
01133       newDocEntry = ReadNextDocEntry( );
01134 
01135       if ( !newDocEntry )
01136       {
01137          break;
01138       }
01139       
01140       // Uncoment this cerr line to be able to 'follow' the DocEntries
01141       // when something *very* strange happens
01142       if( Debug::GetDebugFlag() ) 
01143          std::cerr<<newDocEntry->GetKey()<<" "<<newDocEntry->GetVR()<<std::endl;
01144 
01145        // an Item Starter found elsewhere but in the first position
01146        // of a SeqEntry means previous entry was a Sequence
01147        // but we didn't get it (private Sequence + Implicit VR)
01148        // we have to backtrack.
01149       if ( !first && newDocEntry->IsItemStarter() )
01150       {
01151          // Debug message within the method !
01152          newDocEntry = Backtrack(newDocEntry);
01153       }
01154       else
01155       { 
01156          PreviousDocEntry = newDocEntry; 
01157       }
01158  
01159       used = true;
01160       newDataEntry = dynamic_cast<DataEntry*>(newDocEntry);
01161 
01162       if ( newDataEntry )  
01163       {
01165  
01166          //vr = newDocEntry->GetVR(); // useless ?
01167 
01168          if ( !set->AddEntry( newDataEntry ) )
01169          {
01170             gdcmDebugMacro( "in ParseDES : cannot add a DataEntry "
01171                                  << newDataEntry->GetKey()
01172                                  << " (at offset : 0x(" 
01173                                  << newDataEntry->GetOffset() << ") )" );
01174             used=false;
01175          }
01176          else
01177          {
01178             newDataEntry->Delete();
01179             // Load only if we can add (not a duplicate key)
01180             LoadDocEntry( newDataEntry );
01181          }
01182          if ( newDataEntry->GetElement() == 0x0000 ) // if on group length
01183          {
01184             if ( newDataEntry->GetGroup()%2 != 0 )   // if Shadow Group
01185             {
01186                if ( LoadMode & LD_NOSHADOW ) // if user asked to skip shad.gr
01187                {
01188                   std::string strLgrGroup = newDataEntry->GetString();
01189 
01190                   int lgrGroup;
01191                   //if ( newDataEntry->IsUnfound() ) /?!? JPR
01192                   {
01193                      lgrGroup = atoi(strLgrGroup.c_str());
01194                      Fp->seekg(lgrGroup, std::ios::cur); // Once per Shadow group, when NOSHADOW
01195                      RemoveEntry( newDocEntry );  // Remove and delete
01196                      continue;
01197                   }
01198                }
01199             }
01200          }
01201 
01202          bool delimitor = newDataEntry->IsItemDelimitor(); 
01203          bool outOfBounds = false;
01204          if (!delim_mode )
01205             if ( ((long)(Fp->tellg())-offset) >= l_max ) //Once per DataEntry when no delim mode
01206                outOfBounds = true;
01207 
01208   //       'and then', 'or else' don't exist in C++ :-(
01209   //       if ( (delimitor) || 
01210   //             (!delim_mode && ((long)(Fp->tellg())-offset) >= l_max) ) // Once per DataEntry
01211 
01212          if ( delimitor || outOfBounds )
01213          {
01214             if ( !used )
01215                newDocEntry->Delete();
01216             break;
01217          }
01218 
01219          // Just to make sure we are at the beginning of next entry.
01220          SkipToNextDocEntry(newDocEntry); // FIXME : once per DocEntry, segfault if commented out
01221       }
01222       else
01223       {
01225 
01226          unsigned long l = newDocEntry->GetReadLength();          
01227          if ( l != 0 ) // don't mess the delim_mode for 'zero-length sequence'
01228          {
01229             if ( l == 0xffffffff )
01230             {
01231               delim_mode_intern = true;
01232             }
01233             else
01234             {
01235               delim_mode_intern = false;
01236             }
01237          }
01238 
01239          if ( (LoadMode & LD_NOSHADOWSEQ) && ! delim_mode_intern )
01240          { 
01241            // User asked to skip SeQuences *only* if they belong to Shadow Group
01242             if ( newDocEntry->GetGroup()%2 != 0 )
01243             {
01244                 Fp->seekg( l, std::ios::cur);  // once per SQITEM, when NOSHADOWSEQ
01245                 newDocEntry->Delete();  // Delete, not in the set 
01246                 continue;  
01247             } 
01248          } 
01249          if ( (LoadMode & LD_NOSEQ) && ! delim_mode_intern ) 
01250          {
01251            // User asked to skip *any* SeQuence
01252             Fp->seekg( l, std::ios::cur); // Once per SQ, when NOSEQ
01253             newDocEntry->Delete(); // Delete, not in the set
01254             continue;
01255          }
01256          // delay the dynamic cast as late as possible
01257          newSeqEntry = dynamic_cast<SeqEntry*>(newDocEntry);
01258          
01259          // no other way to create the Delimitor ...
01260          newSeqEntry->SetDelimitorMode( delim_mode_intern );
01261 
01262          // At the top of the hierarchy, stands a Document. When "set"
01263          // is a Document, then we are building the first depth level.
01264          // Hence the SeqEntry we are building simply has a depth
01265          // level of one:
01266         if ( set == this ) // ( dynamic_cast< Document* > ( set ) )
01267          {
01268             newSeqEntry->SetDepthLevel( 1 );
01269          }
01270          // But when "set" is already a SQItem, we are building a nested
01271          // sequence, and hence the depth level of the new SeqEntry
01272          // we are building, is one level deeper:
01273 
01274          // time waste hunting
01275          else if (SQItem *parentSQItem = dynamic_cast< SQItem* > ( set ) )
01276          {
01277             newSeqEntry->SetDepthLevel( parentSQItem->GetDepthLevel() + 1 );
01278          }
01279 
01280          if ( l != 0 )
01281          {  // Don't try to parse zero-length sequences
01282 
01283             gdcmDebugMacro( "Entry in ParseSQ, delim " << delim_mode_intern
01284                                << " at offset 0x(" << std::hex
01285                                << newDocEntry->GetOffset() << ")");
01286 
01287             bool res = ParseSQ( newSeqEntry, 
01288                          newDocEntry->GetOffset(),
01289                          l, delim_mode_intern);
01290 
01291             gdcmDebugMacro( "Exit from ParseSQ, delim " << delim_mode_intern << " -->return : " << res);
01292          }
01293          if ( !set->AddEntry( newSeqEntry ) )
01294          {
01295             gdcmWarningMacro( "in ParseDES : cannot add a SeqEntry "
01296                                 << newSeqEntry->GetKey()
01297                                 << " (at offset : 0x(" 
01298                                 << newSeqEntry->GetOffset() << ") )" ); 
01299             used = false;
01300          }
01301          else
01302          {
01303             newDocEntry->Delete();
01304          }
01305 
01306       // if ( !delim_mode && ((long)(Fp->tellg())-offset) >= l_max) // Once per SeqEntry
01307  
01308          if ( !delim_mode ) // 'and then' doesn't exist in C++ :-(
01309             if ( ((long)(Fp->tellg())-offset) >= l_max) // Once per SeqEntry when no delim mode
01310      
01311          {
01312             if ( !used )
01313                newDocEntry->Delete();
01314             break;
01315          }
01316       }  // end SeqEntry : VR = "SQ"
01317 
01318       if ( !used )
01319       {
01320          newDocEntry->Delete();
01321       }
01322       first = false;
01323       
01324       if (UnexpectedEOF) // some terminator was missing
01325          break;
01326    }                               // end While
01327    gdcmDebugMacro( "Exit from ParseDES, delim-mode " << delim_mode );
01328 }

bool GDCM_NAME_SPACE::Document::ParseSQ SeqEntry seqEntry,
long  offset,
long  l_max,
bool  delim_mode
[private]
 

Parses a Sequence ( SeqEntry after SeqEntry).

Returns:
false if expected fff0,e000 not found

Definition at line 1334 of file gdcmDocument.cxx.

References gdcmWarningMacro, GDCM_NAME_SPACE::DocEntry::IsSequenceDelimitor(), ReadNextDocEntry(), GDCM_NAME_SPACE::SeqEntry::SetDelimitationItem(), and UnexpectedEOF.

01336 {
01337    int SQItemNumber = 0;
01338    bool dlm_mod;
01339    long offsetStartCurrentSQItem = offset;
01340 
01341    while (true)
01342    {
01343       // the first time, we read the fff0,e000 of the first SQItem
01344       DocEntry *newDocEntry = ReadNextDocEntry();
01345 
01346       if ( !newDocEntry )
01347       { 
01348          // The most frequent is when a SQ terminator is missing (?!?)
01349          gdcmWarningMacro("in ParseSQ : should never get here!");
01350          UnexpectedEOF = true;
01351          return false;
01352       }
01353       if ( delim_mode )
01354       {
01355          if ( newDocEntry->IsSequenceDelimitor() )
01356          {
01357             seqEntry->SetDelimitationItem( newDocEntry ); 
01358             newDocEntry->Delete();
01359             break;
01360          }
01361       }
01362       else // ! delim_mode
01363       {
01364          if ( ((long)(Fp->tellg())-offset) >= l_max) // Once per SQItem when no delim mode
01365          {
01366             newDocEntry->Delete();
01367             break;
01368          }
01369       }
01370       // create the current SQItem
01371       SQItem *itemSQ = SQItem::New( seqEntry->GetDepthLevel() );
01372       unsigned int l = newDocEntry->GetReadLength();
01373       
01374       if ( l == 0xffffffff )
01375       {
01376          dlm_mod = true;
01377       }
01378       else
01379       {
01380          dlm_mod = false;
01381       }
01382             
01383       // fill up the current SQItem, starting at the beginning of fff0,e000
01384       
01385       Fp->seekg(offsetStartCurrentSQItem, std::ios::beg);        // Once per SQItem
01386       ParseDES(itemSQ, offsetStartCurrentSQItem, l+8, dlm_mod);
01387       offsetStartCurrentSQItem = Fp->tellg();                    // Once per SQItem
01388  
01389       seqEntry->AddSQItem( itemSQ, SQItemNumber ); 
01390       itemSQ->Delete();
01391       newDocEntry->Delete();
01392       SQItemNumber++;
01393       //if ( !delim_mode && ((long)(Fp->tellg())-offset ) >= l_max ) //JPRx
01394       if ( !delim_mode && (offsetStartCurrentSQItem-offset ) >= l_max )
01395       {
01396          break;
01397       }
01398    }
01399    return true;
01400 }

void GDCM_NAME_SPACE::ElementSet::Print std::ostream &  os = std::cout,
std::string const &  indent = ""
[virtual, inherited]
 

Prints the Header Entries (Dicom Elements) from the H Table.

Parameters:
os ostream to write to
indent Indentation string to be prepended during printing

Reimplemented from GDCM_NAME_SPACE::Base.

Reimplemented in GDCM_NAME_SPACE::DicomDir.

Definition at line 277 of file gdcmElementSet.cxx.

References GDCM_NAME_SPACE::DataEntry::FLAG_PIXELDATA, GDCM_NAME_SPACE::DocEntrySet::GetDataEntry(), GDCM_NAME_SPACE::Base::PrintLevel, GDCM_NAME_SPACE::DataEntry::SetFlag(), and GDCM_NAME_SPACE::ElementSet::TagHT.

Referenced by GDCM_NAME_SPACE::FileHelper::Print().

00278 {
00279    // Let's change the 'warning value' for Pixel Data,
00280    // to avoid human reader to be confused by 'gdcm::NotLoaded'.   
00281    DataEntry *pixelElement = GetDataEntry(0x7fe0,0x0010);
00282    if ( pixelElement != 0 )
00283    {
00284       pixelElement->SetFlag( DataEntry::FLAG_PIXELDATA );
00285    }
00286 
00287    for( TagDocEntryHT::const_iterator i = TagHT.begin(); i != TagHT.end(); ++i)
00288    {
00289       DocEntry *entry = i->second;
00290 
00291       entry->SetPrintLevel(PrintLevel);
00292       entry->Print(os);   
00293 
00294       if ( dynamic_cast<SeqEntry*>(entry) )
00295       {
00296          // Avoid the newline for a sequence:
00297          continue;
00298       }
00299       os << std::endl;
00300    }
00301 }

void GDCM_NAME_SPACE::Document::ReadBegBuffer size_t  l  )  throw ( FormatError ) [private]
 

Reads a given length of bytes (in order to avoid to many CPU time-consuming fread-s).

Parameters:
l length to read

Definition at line 926 of file gdcmDocument.cxx.

Referenced by FindDocEntryLengthOBOrOW(), and ReadNextDocEntry().

00928 {   
00929    Fp->read (BegBuffer, (size_t)l);
00930    if ( Fp->fail() )
00931    {
00932       throw FormatError( "Document::ReadBegBuffer()", " file error." );
00933    }
00934    if ( Fp->eof() )
00935    {
00936       throw FormatError( "Document::ReadBegBuffer()", "EOF." );
00937    }
00938    PtrBegBuffer = BegBuffer;
00939    CurrentOffsetPosition+=l;
00940 }

uint16_t GDCM_NAME_SPACE::Document::ReadInt16  )  throw ( FormatError ) [protected]
 

Reads a supposed to be 16 Bits integer (swaps it depending on processor endianness).

Returns:
read value

Definition at line 946 of file gdcmDocument.cxx.

Referenced by GDCM_NAME_SPACE::File::ReadTag().

00948 {
00949    uint16_t g;
00950    Fp->read ((char*)&g, (size_t)2);
00951    if ( Fp->fail() )
00952    {
00953       throw FormatError( "Document::ReadInt16()", " file error." );
00954    }
00955    if ( Fp->eof() )
00956    {
00957       throw FormatError( "Document::ReadInt16()", "EOF." );
00958    }
00959    g = SwapShort(g); 
00960    return g;
00961 }

uint32_t GDCM_NAME_SPACE::Document::ReadInt32  )  throw ( FormatError ) [protected]
 

Reads a supposed to be 32 Bits integer (swaps it depending on processor endianness).

Returns:
read value

Definition at line 980 of file gdcmDocument.cxx.

Referenced by GDCM_NAME_SPACE::File::ComputeRLEInfo(), FindDocEntryLengthOBOrOW(), and GDCM_NAME_SPACE::File::ReadTagLength().

00982 {
00983    uint32_t g;
00984    Fp->read ((char*)&g, (size_t)4);
00985    if ( Fp->fail() )
00986    {
00987       throw FormatError( "Document::ReadInt32()", " file error." );
00988    }
00989    if ( Fp->eof() )
00990    {
00991       throw FormatError( "Document::ReadInt32()", "EOF." );
00992    }
00993    g = SwapLong(g);
00994    return g;
00995 }

DocEntry * GDCM_NAME_SPACE::Document::ReadNextDocEntry  )  [private]
 

Read the next tag 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).

Returns:
On succes : the newly created DocEntry, NULL on failure.
Todo:
: fixme If inside a supposed to be UN DataElement (but SQ according to a private dictionnary) there is some more supposed to be UN DataElements, it will probabely fail. --> find a -non time consuming- trick to store changeFromUN info at DataElement level, not at the Document level.

Definition at line 2203 of file gdcmDocument.cxx.

References changeFromUN, CurrentElem, CurrentGroup, GDCM_NAME_SPACE::RefCounter::Delete(), GDCM_NAME_SPACE::ExplicitVR, Filetype, FindDocEntryLength(), FindDocEntryVR(), GDCM_NAME_SPACE::GDCM_VRUNKNOWN, gdcmWarningMacro, GDCM_NAME_SPACE::DocEntrySet::GetDictEntry(), GetInt16(), GDCM_NAME_SPACE::DocEntry::GetKey(), GDCM_NAME_SPACE::DictEntry::GetVR(), Group0002Parsed, HandleBrokenEndian(), HandleOutOfGroup0002(), HasDCMPreamble, GDCM_NAME_SPACE::DocEntrySet::NewDataEntry(), GDCM_NAME_SPACE::DocEntrySet::NewSeqEntry(), ReadBegBuffer(), GDCM_NAME_SPACE::DocEntry::SetImplicitVR(), GDCM_NAME_SPACE::DocEntry::SetOffset(), GDCM_NAME_SPACE::DataEntry::STATE_NOTLOADED, and GDCM_NAME_SPACE::RefCounter::Unregister().

Referenced by ParseDES(), and ParseSQ().

02204 {
02205    try
02206    {
02207       ReadBegBuffer(8); // Avoid to many time consuming freads
02208       //CurrentGroup = ReadInt16();
02209       //CurrentElem  = ReadInt16();
02210    }
02211    catch ( FormatError )
02212    {
02213       // We reached the EOF (or an error occured) therefore
02214       // header parsing has to be considered as finished.
02215       return 0;
02216    }
02217    
02218    changeFromUN = false;
02219    CurrentGroup = GetInt16();
02220    CurrentElem  = GetInt16();
02221       
02222    // In 'true DICOM' files Group 0002 is always little endian
02223    if ( HasDCMPreamble )
02224    {
02225       if ( !Group0002Parsed && CurrentGroup != 0x0002) // avoid calling a function when useless
02226          HandleOutOfGroup0002(CurrentGroup, CurrentElem);
02227       else
02228          // Sometimes file contains groups of tags with reversed endianess.
02229          HandleBrokenEndian(CurrentGroup, CurrentElem);
02230     }
02231 
02232    VRKey vr = FindDocEntryVR();
02233    VRKey realVR = vr;
02234 
02235    if ( vr == GDCM_VRUNKNOWN )
02236    {
02237       if ( CurrentElem == 0x0000 ) // Group Length
02238       {
02239          realVR = "UL";     // must be UL
02240       }
02241       else if (CurrentGroup == 0xfffe) // Don't get DictEntry for Delimitors
02242       {
02243          realVR = "UL";
02244       }
02245 
02246       // Was commented out in order not to generate 'Shadow Groups' where some 
02247       // Data Elements are Explicit VR and some other ones Implicit VR
02248       // -> Better we fix the problem at Write time
02249      
02250       else if (CurrentGroup%2 == 1 )
02251       { 
02252          if (CurrentElem >= 0x0010 && CurrentElem <=0x00ff )
02253             // DICOM PS 3-5 7.8.1 a) states that :
02254             // Private Creator Data Elements numbered (gggg,0010-00FF) (gggg is odd)
02255             // attributes have to be LO (Long String) and the VM shall be equal to 1
02256             realVR = "LO";
02257     
02258             // Seems not to be true
02259             // Still in gdcmtk, David Clunnie disagrees, Marco Eichelberg says it's OK ...
02260             // We let it for a while? 
02261             //(We should check length==4, for more security, but we don't have it yet !)
02262          else if ( CurrentElem == 0x0001)
02263             realVR = "UL"; // Private Group Length To End      
02264       }
02265       
02266       else
02267       {
02268          DictEntry *dictEntry = GetDictEntry(CurrentGroup,CurrentElem);//only when ImplicitVR
02269          if ( dictEntry )
02270          {
02271             realVR = dictEntry->GetVR();
02272             dictEntry->Unregister(); // GetDictEntry registered it 
02273          }
02274       }
02275    }
02276 
02277    // if UN found, let's check the dictionary, and trust it!
02278    // (maybe a private dictionary exists?)    
02279    else if (vr == "UN")
02280    {
02281       DictEntry *dictEntry = GetDictEntry(CurrentGroup,CurrentElem);
02282       if ( dictEntry )
02283       {
02284          realVR = dictEntry->GetVR(); 
02285          dictEntry->Unregister(); // GetDictEntry registered it
02286 
02287          // for VR = "UN", length is always stored on 4 bytes.
02288          changeFromUN=true;
02293       }   
02294    }
02295 
02296 
02297    DocEntry *newEntry;
02298    //if ( Global::GetVR()->IsVROfSequence(realVR) )
02299    if (realVR == "SQ")
02300    {
02301       newEntry = NewSeqEntry(CurrentGroup, CurrentElem);
02302    }
02303    else
02304    {
02305       newEntry = NewDataEntry(CurrentGroup, CurrentElem, realVR);
02306       static_cast<DataEntry *>(newEntry)->SetState(DataEntry::STATE_NOTLOADED);
02307    }
02308 
02309    if ( vr == GDCM_VRUNKNOWN )
02310    {
02311       if ( Filetype == ExplicitVR )
02312       {
02313          // We thought this was explicit VR, but we end up with an
02314          // implicit VR tag. Let's backtrack.
02315  
02316          //if ( newEntry->GetGroup() != 0xfffe ) 
02317          if (CurrentGroup != 0xfffe)
02318          { 
02319             int offset = Fp->tellg();//Only when heuristic for Explicit/Implicit was wrong
02320 
02321             gdcmWarningMacro("Entry (" << newEntry->GetKey() << ") at x("
02322                      <<  offset << ") should be Explicit VR");
02323           }
02324       }
02325       newEntry->SetImplicitVR();
02326    }
02327 
02328    try
02329    {
02330       FindDocEntryLength(newEntry);
02331    }
02332    catch ( FormatError )
02333    {
02334       // Call it quits
02335       newEntry->Delete();
02336       return 0;
02337    }
02338 
02339    newEntry->SetOffset(Fp->tellg());  // for each DocEntry
02340    return newEntry;
02341 }

void GDCM_NAME_SPACE::RefCounter::Register  )  [inline, inherited]
 

Register the object.

Remarks:
It increments the reference counting

Definition at line 46 of file gdcmRefCounter.h.

Referenced by GDCM_NAME_SPACE::SQItem::AddEntry(), GDCM_NAME_SPACE::SeqEntry::AddSQItem(), GDCM_NAME_SPACE::SeqEntry::Copy(), GDCM_NAME_SPACE::DicomDir::Copy(), GDCM_NAME_SPACE::FileHelper::FileHelper(), GDCM_NAME_SPACE::DocEntrySet::GetDictEntry(), GDCM_NAME_SPACE::DocEntry::GetName(), GDCM_NAME_SPACE::DocEntry::GetVM(), GDCM_NAME_SPACE::DocEntrySet::InsertEntryString(), GDCM_NAME_SPACE::CommandManager::InSetCommand(), GDCM_NAME_SPACE::DocEntryArchive::Push(), and GDCM_NAME_SPACE::SeqEntry::SetDelimitationItem().

00046 { RefCount++; }

bool GDCM_NAME_SPACE::ElementSet::RemoveEntry DocEntry entryToRemove  )  [virtual, inherited]
 

Clear the hash table from given entry AND delete the entry.

Parameters:
entryToRemove Entry to remove AND delete.

Implements GDCM_NAME_SPACE::DocEntrySet.

Definition at line 122 of file gdcmElementSet.cxx.

References GDCM_NAME_SPACE::DocEntry::GetKey(), GDCM_NAME_SPACE::ElementSet::TagHT, and GDCM_NAME_SPACE::RefCounter::Unregister().

Referenced by Backtrack(), GDCM_NAME_SPACE::DicomDir::NewMeta(), GDCM_NAME_SPACE::DocEntryArchive::Push(), and GDCM_NAME_SPACE::DocEntryArchive::Restore().

00123 {
00124    const TagKey &key = entryToRemove->GetKey();
00125    if ( TagHT.count(key) == 1 )
00126    {
00127       TagHT.erase(key);
00128       entryToRemove->Unregister();
00129       return true;
00130    }
00131 
00132    gdcmWarningMacro( "Key not present : " << key);
00133    return false ;
00134 }

bool GDCM_NAME_SPACE::DocEntrySet::SetEntryBinArea uint8_t *  content,
int  lgth,
DataEntry entry
[inherited]
 

Accesses an existing DataEntry (i.e. a Dicom Element) and modifies its content with the given value.

Parameters:
content new value (void* -> uint8_t*) to substitute with
entry Entry to be modified
lgth new value length

Definition at line 195 of file gdcmDocEntrySet.cxx.

References GDCM_NAME_SPACE::DataEntry::SetBinArea(), and GDCM_NAME_SPACE::DocEntry::SetLength().

00196 {
00197    if (entry)
00198    {
00199       entry->SetLength(lgth);
00200       entry->SetBinArea(content);  
00201       return true;
00202    }
00203    return false;
00204 }

bool GDCM_NAME_SPACE::DocEntrySet::SetEntryBinArea uint8_t *  content,
int  lgth,
uint16_t  group,
uint16_t  elem
[inherited]
 

Accesses an existing DocEntry (i.e. a Dicom Element) through its (group, element) and modifies its content with the given value.

Parameters:
content new value (void* -> uint8_t*) to substitute with
lgth new value length
group group number of the Dicom Element to modify
elem element number of the Dicom Element to modify

Definition at line 158 of file gdcmDocEntrySet.cxx.

References gdcmWarningMacro, and GDCM_NAME_SPACE::DocEntrySet::GetDataEntry().

Referenced by GDCM_NAME_SPACE::DocEntrySet::InsertEntryBinArea(), and GDCM_NAME_SPACE::FileHelper::SetEntryBinArea().

00160 {
00161    DataEntry *entry = GetDataEntry(group, elem);
00162    if (!entry )
00163    {
00164       gdcmWarningMacro( "No corresponding DataEntry " << std::hex << group <<
00165                         "," << elem << " element (try promotion first).");
00166       return false;
00167    }
00168 
00169    return SetEntryBinArea(content,lgth,entry);
00170 } 

bool GDCM_NAME_SPACE::DocEntrySet::SetEntryString std::string const &  content,
DataEntry entry
[inherited]
 

Accesses an existing DocEntry (i.e. a Dicom Element) and modifies its content with the given value.

Parameters:
content new value (string) to substitute with
entry Entry to be modified

Definition at line 178 of file gdcmDocEntrySet.cxx.

References GDCM_NAME_SPACE::DataEntry::SetString().

00179 {
00180    if (entry)
00181    {
00182       entry->SetString(content);
00183       return true;
00184    }
00185    return false;
00186 }

bool GDCM_NAME_SPACE::DocEntrySet::SetEntryString std::string const &  content,
uint16_t  group,
uint16_t  elem
[inherited]
 

Accesses an existing DocEntry (i.e. a Dicom Element) through its (group, element) and modifies its content with the given value.

Parameters:
content new value (string) to substitute with
group group number of the Dicom Element to modify
elem element number of the Dicom Element to modify

Definition at line 136 of file gdcmDocEntrySet.cxx.

References gdcmWarningMacro, and GDCM_NAME_SPACE::DocEntrySet::GetDataEntry().

Referenced by GDCM_NAME_SPACE::File::AnonymizeFile(), GDCM_NAME_SPACE::DocEntrySet::InsertEntryString(), and GDCM_NAME_SPACE::FileHelper::SetEntryString().

00138 {
00139    DataEntry *entry = GetDataEntry(group, elem);
00140    if (!entry )
00141    {
00142       gdcmWarningMacro( "No corresponding DataEntry " << std::hex << group <<
00143                          "," << elem << " element (try promotion first).");
00144       return false;
00145    }
00146    return SetEntryString(content,entry);
00147 }

virtual void GDCM_NAME_SPACE::Document::SetFileName std::string const &  fileName  )  [inline, virtual]
 

Accessor to Filename.

Reimplemented in GDCM_NAME_SPACE::DicomDir.

Definition at line 80 of file gdcmDocument.h.

Referenced by GDCM_NAME_SPACE::SerieHelper::AddFileName(), GDCM_NAME_SPACE::DicomDir::CreateDicomDirChainedList(), Document(), vtkGdcmReader::LoadFileInformation(), and GDCM_NAME_SPACE::FileHelper::SetFileName().

00081                    { if (Filename != fileName)
00082                         Filename = fileName, IsDocumentModified = true; }

void GDCM_NAME_SPACE::Document::SetLoadMode int  mode  )  [inline]
 

Sets the LoadMode as a boolean string. LD_NOSEQ, LD_NOSHADOW, LD_NOSHADOWSEQ ... (nothing more, right now) WARNING : before using NO_SHADOW, be sure *all* your files contain accurate values in the 0x0000 element (if any) of *each* Shadow Group. The parser will fail if the size is wrong !

Parameters:
mode Load mode to be used

Definition at line 107 of file gdcmDocument.h.

Referenced by GDCM_NAME_SPACE::SerieHelper::AddFileName(), GDCM_NAME_SPACE::DicomDir::CreateDicomDirChainedList(), vtkGdcmReader::LoadFileInformation(), and GDCM_NAME_SPACE::FileHelper::SetLoadMode().

00107                                { if (LoadMode != mode) 
00108                                      LoadMode=mode, IsDocumentModified = true; }

void GDCM_NAME_SPACE::Document::SetMaxSizeLoadEntry long  newSize  ) 
 

during parsing, Header Elements too long are not loaded in memory

Parameters:
newSize new size

Definition at line 2182 of file gdcmDocument.cxx.

References MaxSizeLoadEntry.

Referenced by Document().

02183 {
02184    if ( newSize < 0 )
02185    {
02186       return;
02187    }
02188    if ((uint32_t)newSize >= (uint32_t)0xffffffff )
02189    {
02190       MaxSizeLoadEntry = 0xffffffff;
02191       return;
02192    }
02193    MaxSizeLoadEntry = newSize;
02194 }

void GDCM_NAME_SPACE::Base::SetPrintLevel int  level  )  [inline, inherited]
 

Sets the print level for the Dicom Header Elements.

Note:
0 for Light Print; 1 for 'medium' Print, 2 for Heavy Print

Definition at line 47 of file gdcmBase.h.

Referenced by GDCM_NAME_SPACE::FileHelper::Print(), and GDCM_NAME_SPACE::DicomDir::Print().

00047 { PrintLevel = level; }

bool GDCM_NAME_SPACE::Document::SetShaDict DictKey const &  dictName  ) 
 

Set the shadow dictionary used.

Parameters:
dictName name of the dictionary to use in shadow

Definition at line 341 of file gdcmDocument.cxx.

References GDCM_NAME_SPACE::DictSet::GetDict(), GDCM_NAME_SPACE::Global::GetDicts(), and RefShaDict.

00342 {
00343    RefShaDict = Global::GetDicts()->GetDict(dictName);
00344    return !RefShaDict;
00345 }

bool GDCM_NAME_SPACE::Document::SetShaDict Dict dict  ) 
 

Set the shadow dictionary used.

Parameters:
dict dictionary to use in shadow

Definition at line 331 of file gdcmDocument.cxx.

References RefShaDict.

00332 {
00333    RefShaDict = dict;
00334    return !RefShaDict;
00335 }

void GDCM_NAME_SPACE::Document::SkipBytes uint32_t  nBytes  )  [inline, protected]
 

skips bytes inside the source file

Definition at line 126 of file gdcmDocument.h.

Referenced by GDCM_NAME_SPACE::File::ComputeJPEGFragmentInfo(), GDCM_NAME_SPACE::File::ComputeRLEInfo(), FindDocEntryLengthOBOrOW(), and SkipDocEntry().

00126 { Fp->seekg((long)nBytes, std::ios::cur);} 

void GDCM_NAME_SPACE::Document::SkipDocEntry DocEntry entry  )  [private]
 

Skip a given Header Entry.

Parameters:
entry entry to skip

Definition at line 1744 of file gdcmDocument.cxx.

References GDCM_NAME_SPACE::DocEntry::GetLength(), and SkipBytes().

01745 {
01746    SkipBytes(entry->GetLength());
01747 }

void GDCM_NAME_SPACE::Document::SkipToNextDocEntry DocEntry currentDocEntry  )  [private]
 

Skips to the beginning of the next Header Entry.

Parameters:
currentDocEntry entry to skip

Definition at line 1753 of file gdcmDocument.cxx.

References GDCM_NAME_SPACE::DocEntry::GetGroup(), GDCM_NAME_SPACE::DocEntry::GetOffset(), and GDCM_NAME_SPACE::DocEntry::GetReadLength().

01754 {
01755    long l = currentDocEntry->GetReadLength();
01756    if ( l == -1 ) // length = 0xffff shouldn't appear here ...
01757                   // ... but PMS imagers happen !
01758       return;
01759    Fp->seekg((size_t)(currentDocEntry->GetOffset()), std::ios::beg); //FIXME :each DocEntry
01760    if (currentDocEntry->GetGroup() != 0xfffe)  // for fffe pb
01761    {
01762       Fp->seekg( l,std::ios::cur);                                 //FIXME :each DocEntry
01763    }
01764 }

double GDCM_NAME_SPACE::Document::SwapDouble double  a  )  [private]
 

Swaps back the bytes of 8-byte long 'double' accordingly to processor order.

Returns:
The properly swaped 64 bits double.

Definition at line 551 of file gdcmDocument.cxx.

References gdcmErrorMacro, and SwapCode.

00552 {
00553    switch (SwapCode)
00554    {
00555       // There were no 'double' at ACR-NEMA time.
00556       // We just have to deal with 'straight Little Endian' and 
00557       // 'straight Big Endian'
00558       case 1234 :
00559          break;
00560       case 4321 :
00561          {
00562          char *beg = (char *)&a;
00563          char *end = beg + 7;
00564          char t;
00565          for (unsigned int i = 0; i<7; i++)
00566          {
00567             t    = *beg;
00568             *beg = *end;
00569             *end = t;
00570             beg++,
00571             end--;  
00572          }
00573          }
00574          break;   
00575       default :
00576          gdcmErrorMacro( "Unexpected swap code:" << SwapCode );
00577          a = 0.;
00578    }
00579    return a;
00580 } 

uint32_t GDCM_NAME_SPACE::Document::SwapLong uint32_t  a  )  [private]
 

Swaps back the bytes of 4-byte long integer accordingly to processor order.

Returns:
The properly swaped 32 bits integer.

Definition at line 519 of file gdcmDocument.cxx.

References gdcmErrorMacro, and SwapCode.

Referenced by GetInt32().

00520 {
00521    switch (SwapCode)
00522    {
00523       case 1234 :
00524          break;
00525       case 4321 :
00526 //         a=( ((a<<24) & 0xff000000) | ((a<<8)  & 0x00ff0000) | 
00527 //             ((a>>8)  & 0x0000ff00) | ((a>>24) & 0x000000ff) );
00528 // save CPU time
00529          a=( ( a<<24)               | ((a<<8)  & 0x00ff0000) | 
00530              ((a>>8)  & 0x0000ff00) |  (a>>24)                );
00531          break;   
00532       case 3412 :
00533 //       a=( ((a<<16) & 0xffff0000) | ((a>>16) & 0x0000ffff) );
00534          a=( (a<<16)                | (a>>16)  );
00535          break;  
00536       case 2143 :
00537          a=( ((a<< 8) & 0xff00ff00) | ((a>>8) & 0x00ff00ff)  );
00538       break;
00539       default :
00540          gdcmErrorMacro( "Unexpected swap code:" << SwapCode );
00541          a = 0;
00542    }
00543    return a;
00544 } 

uint16_t GDCM_NAME_SPACE::Document::SwapShort uint16_t  a  )  [private]
 

Swaps the bytes so they agree with the processor order.

Returns:
The properly swaped 16 bits integer.

Definition at line 503 of file gdcmDocument.cxx.

References SwapCode.

Referenced by GetInt16(), and HandleOutOfGroup0002().

00504 {
00505    if ( SwapCode == 4321 || SwapCode == 2143 )
00506    {
00507       //a = ((( a << 8 ) & 0xff00 ) | (( a >> 8 ) & 0x00ff ) );
00508       // Save CPU time
00509       a = ( a << 8 ) | ( a >> 8 );
00510    }
00511    return a;
00512 }

void GDCM_NAME_SPACE::Document::SwitchByteSwapCode  )  [private]
 

Change the Byte Swap code.

Definition at line 2155 of file gdcmDocument.cxx.

References gdcmDebugMacro, and SwapCode.

Referenced by HandleBrokenEndian(), and HandleOutOfGroup0002().

02156 {
02157    gdcmDebugMacro( "Switching Byte Swap code from "<< SwapCode
02158                      << " at: 0x" << std::hex << Fp->tellg() );  // Only when DEBUG
02159    if ( SwapCode == 1234 ) 
02160    {
02161       SwapCode = 4321;
02162    }
02163    else if ( SwapCode == 4321 ) 
02164    {
02165       SwapCode = 1234;
02166    }
02167    else if ( SwapCode == 3412 ) 
02168    {
02169       SwapCode = 2143;
02170    }
02171    else if ( SwapCode == 2143 )
02172    {
02173       SwapCode = 3412;
02174    }
02175    gdcmDebugMacro( " Into: "<< SwapCode );
02176 }

void GDCM_NAME_SPACE::RefCounter::Unregister  )  [inline, inherited]
 

Unregister the object.

Remarks:
It decrements the reference counting

Definition at line 50 of file gdcmRefCounter.h.

Referenced by ReadNextDocEntry(), GDCM_NAME_SPACE::SQItem::RemoveEntry(), GDCM_NAME_SPACE::ElementSet::RemoveEntry(), and GDCM_NAME_SPACE::FileHelper::~FileHelper().

00051    {
00052 //std::cout <<"================Unreg " << typeid(*this).name() << std::endl;
00053       RefCount--;
00054       if(RefCount<=0)
00055         delete this;
00056    }

uint32_t GDCM_NAME_SPACE::Document::UnswapLong uint32_t  a  )  [inline, private]
 

Unswaps back the bytes of 4-byte long integer so they agree with the processor order.

Definition at line 200 of file gdcmDocument.h.

00200 { return SwapLong(a);}

uint16_t GDCM_NAME_SPACE::Document::UnswapShort uint16_t  a  )  [inline, private]
 

Unswaps back the bytes of 2-bytes long integer so they agree with the processor order.

Definition at line 197 of file gdcmDocument.h.

00197 { return SwapShort(a);}

void GDCM_NAME_SPACE::ElementSet::WriteContent std::ofstream *  fp,
FileType  filetype,
bool  dummy
[virtual, inherited]
 

Writes the Header Entries (Dicom Elements) from the H Table.

Parameters:
fp ofstream to write to
filetype ExplicitVR/ImplicitVR/ACR/ACR_LIBIDO/JPEG/JPEG2000/...

Implements GDCM_NAME_SPACE::DocEntrySet.

Definition at line 52 of file gdcmElementSet.cxx.

References GDCM_NAME_SPACE::ACR, GDCM_NAME_SPACE::ACR_LIBIDO, GDCM_NAME_SPACE::ElementSet::MayIWrite(), and GDCM_NAME_SPACE::ElementSet::TagHT.

Referenced by WriteContent().

00053 {
00054    bool insideMetaElements     = false;
00055    bool yetOutsideMetaElements = false;
00056    
00057    for (TagDocEntryHT::const_iterator i = TagHT.begin(); 
00058                                      i != TagHT.end(); 
00059                                     ++i)
00060    {
00061         int group = (i->second)->GetGroup();
00062        
00063        if (yetOutsideMetaElements==false && group == 0x0002)
00064           insideMetaElements = true;
00065     
00066        if (insideMetaElements == true && group != 0x0002)
00067        {
00068           yetOutsideMetaElements = true;
00069           insideMetaElements     = false;
00070        }
00071    
00072        // depending on the gdcm::Document type 
00073        // (gdcm::File; gdcm::DicomDir, (more to come ?)
00074        // some groups *cannot* be present.
00075        // We hereby protect gdcm for writting stupid things
00076        // if they were found in the original document. 
00077        if ( !MayIWrite( group ) )
00078           continue;
00079   
00080       // Skip 'Group Length' element, since it may be wrong.
00081       //       except for Group 0x0002
00082       // ( keep it as well for Group 0x0008 of ACR Files, 
00083       //  since some ACR readers *need* it )
00084       
00085        if ( (i->second)->GetElement() != 0x0000 
00086            || 
00087             (  (i->second)->GetGroup() == 0x0002 
00088              ||( (filetype == ACR || filetype == ACR_LIBIDO ) && (i->second)->GetGroup() == 0x0008 ) )
00089         )
00090        {
00091              // There are DocEntries, written recursively
00092              i->second->WriteContent(fp, filetype, insideMetaElements );
00093        }             
00094    } 
00095 }

void GDCM_NAME_SPACE::Document::WriteContent std::ofstream *  fp,
FileType  filetype
 

Writes in a file all the Entries (Dicom Elements).

Parameters:
fp file pointer on an already open file (actually: Output File Stream)
filetype Type of the File to be written (ACR-NEMA, ExplicitVR, ImplicitVR)

Definition at line 696 of file gdcmDocument.cxx.

References GDCM_NAME_SPACE::ExplicitVR, GDCM_NAME_SPACE::ImplicitVR, GDCM_NAME_SPACE::JPEG, GDCM_NAME_SPACE::JPEG2000, and GDCM_NAME_SPACE::ElementSet::WriteContent().

Referenced by GDCM_NAME_SPACE::File::Write().

00697 {
00698    // Skip if user wants to write an ACR-NEMA file
00699 
00700    if ( filetype == ImplicitVR || filetype == ExplicitVR ||
00701         filetype == JPEG || filetype == JPEG2000 )
00702    {
00703       // writing Dicom File Preamble
00704       char filePreamble[128];
00705       memset(filePreamble, 0, 128);
00706       fp->write(filePreamble, 128);
00707       fp->write("DICM", 4);
00708    }
00709    /*
00710     * \todo rewrite later, if really usefull
00711     *       - 'Group Length' element is optional in DICOM
00712     *       - but un-updated odd groups lengthes can causes pb
00713     *         (xmedcon breaker)
00714     *
00715     * if ( (filetype == ImplicitVR) || (filetype == ExplicitVR) )
00716     *    UpdateGroupLength(false,filetype);
00717     * if ( filetype == ACR)
00718     *    UpdateGroupLength(true,ACR);
00719     *
00720     * --> Computing group length for groups with embeded Sequences
00721     * --> was too much tricky / we were [in a hurry / too lazy]
00722     * --> We don't write the element 0x0000 (group length)
00723     */
00724 
00725    ElementSet::WriteContent(fp, filetype, false); // This one is recursive
00726 }


Member Data Documentation

bool GDCM_NAME_SPACE::Document::Abort [mutable, protected]
 

Definition at line 235 of file gdcmDocument.h.

Referenced by CallStartMethod(), GDCM_NAME_SPACE::DicomDir::CreateDicomDirChainedList(), GDCM_NAME_SPACE::DicomDir::DoTheLoadingJob(), and GDCM_NAME_SPACE::DicomDir::Initialize().

char GDCM_NAME_SPACE::Document::BegBuffer[8] [private]
 

buffer to avoid some freads

Definition at line 260 of file gdcmDocument.h.

bool GDCM_NAME_SPACE::Document::changeFromUN [private]
 

to indicate if last supposed to be UN DataElement is not (according to a private Dicom dictionary)

Definition at line 266 of file gdcmDocument.h.

Referenced by Document(), and ReadNextDocEntry().

uint16_t GDCM_NAME_SPACE::Document::CurrentElem [protected]
 

to allow any inner method to know current tag Element number

Definition at line 252 of file gdcmDocument.h.

Referenced by ReadNextDocEntry().

uint16_t GDCM_NAME_SPACE::Document::CurrentGroup [protected]
 

to allow any inner method to know current tag Group number

Definition at line 250 of file gdcmDocument.h.

Referenced by FindDocEntryVR(), and ReadNextDocEntry().

size_t GDCM_NAME_SPACE::Document::CurrentOffsetPosition [private]
 

to avoid time consuming ftellg

Definition at line 263 of file gdcmDocument.h.

Referenced by CheckSwap(), Document(), and FindDocEntryVR().

std::string GDCM_NAME_SPACE::Document::Filename [protected]
 

Refering underlying filename.

Definition at line 131 of file gdcmDocument.h.

Referenced by GDCM_NAME_SPACE::File::AnonymizeNoLoad(), DoTheLoadingDocumentJob(), and OpenFile().

FileType GDCM_NAME_SPACE::Document::Filetype [protected]
 

ACR, ACR_LIBIDO, ExplicitVR, ImplicitVR, Unknown.

Definition at line 157 of file gdcmDocument.h.

Referenced by CheckSwap(), Document(), DoTheLoadingDocumentJob(), FindDocEntryVR(), GetFileType(), HandleOutOfGroup0002(), Initialize(), IsParsable(), GDCM_NAME_SPACE::DicomDir::IsReadable(), and ReadNextDocEntry().

std::ifstream* GDCM_NAME_SPACE::Document::Fp [protected]
 

File Pointer, opened during Document parsing.

Definition at line 154 of file gdcmDocument.h.

Referenced by GDCM_NAME_SPACE::File::ComputeJPEGFragmentInfo(), GDCM_NAME_SPACE::File::ComputeRLEInfo(), Document(), DoTheLoadingDocumentJob(), GDCM_NAME_SPACE::File::DoTheLoadingJob(), GDCM_NAME_SPACE::DicomDir::DoTheLoadingJob(), GDCM_NAME_SPACE::File::ReadEncapsulatedBasicOffsetTable(), and GDCM_NAME_SPACE::File::ReadTag().

bool GDCM_NAME_SPACE::Document::Group0002Parsed [protected]
 

whether we already parsed group 0002 (Meta Elements)

Definition at line 148 of file gdcmDocument.h.

Referenced by Document(), DoTheLoadingDocumentJob(), HandleOutOfGroup0002(), and ReadNextDocEntry().

bool GDCM_NAME_SPACE::Document::HasDCMPreamble [protected]
 

whether file has a DCM Preamble

Definition at line 151 of file gdcmDocument.h.

Referenced by OpenFile(), and ReadNextDocEntry().

const unsigned int GDCM_NAME_SPACE::Document::HEADER_LENGTH_TO_READ [static, protected]
 

After opening the file, we read HEADER_LENGTH_TO_READ bytes.

Definition at line 160 of file gdcmDocument.h.

bool GDCM_NAME_SPACE::Document::IsDocumentAlreadyLoaded [protected]
 

Whether the gdcm::Document is already parsed/loaded : False from the creation of the gdcm::Document untill gdcm::Document:Load().

Definition at line 180 of file gdcmDocument.h.

Referenced by Document(), and DoTheLoadingDocumentJob().

bool GDCM_NAME_SPACE::Document::IsDocumentModified [protected]
 

Whether the gdcm::Document was modified since the last Load().

Definition at line 183 of file gdcmDocument.h.

Referenced by Document(), and DoTheLoadingDocumentJob().

int GDCM_NAME_SPACE::Document::LoadMode [protected]
 

Bit string integer (each one considered as a boolean) Bit 0 : Skip Sequences, if possible Bit 1 : Skip Shadow Groups if possible Probabely, some more to add.

Definition at line 175 of file gdcmDocument.h.

Referenced by GDCM_NAME_SPACE::DicomDir::CreateDicomDirChainedList(), and Document().

const unsigned int GDCM_NAME_SPACE::Document::MAX_SIZE_LOAD_ELEMENT_VALUE = 0xfff [static, protected]
 

Elements whose value is longer than MAX_SIZE_LOAD_ELEMENT_VALUE are NOT loaded.

Definition at line 163 of file gdcmDocument.h.

Referenced by Document().

uint32_t GDCM_NAME_SPACE::Document::MaxSizeLoadEntry [protected]
 

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 247 of file gdcmDocument.h.

Referenced by LoadDocEntry(), and SetMaxSizeLoadEntry().

DocEntry* GDCM_NAME_SPACE::DocEntrySet::PreviousDocEntry [protected, inherited]
 

To be able to backtrack (Private Sequence, Implicit VR related pb).

Definition at line 128 of file gdcmDocEntrySet.h.

Referenced by Backtrack(), and GDCM_NAME_SPACE::DocEntrySet::DocEntrySet().

int GDCM_NAME_SPACE::Base::PrintLevel [protected, inherited]
 

Amount of printed details for each Dicom Entries : 0 : stands for the least detail level.

Definition at line 55 of file gdcmBase.h.

Referenced by GDCM_NAME_SPACE::SeqEntry::Print(), GDCM_NAME_SPACE::FileHelper::Print(), GDCM_NAME_SPACE::ElementSet::Print(), GDCM_NAME_SPACE::DocEntry::Print(), GDCM_NAME_SPACE::DictEntry::Print(), GDCM_NAME_SPACE::DicomDirStudy::Print(), GDCM_NAME_SPACE::DicomDirSerie::Print(), GDCM_NAME_SPACE::DicomDirPatient::Print(), GDCM_NAME_SPACE::DicomDirMeta::Print(), GDCM_NAME_SPACE::DicomDir::Print(), and GDCM_NAME_SPACE::DataEntry::Print().

float GDCM_NAME_SPACE::Document::Progress [protected]
 

value of the ??? for any progress bar

Definition at line 234 of file gdcmDocument.h.

Referenced by CallEndMethod(), CallStartMethod(), GDCM_NAME_SPACE::DicomDir::CreateDicomDirChainedList(), GDCM_NAME_SPACE::DicomDir::DoTheLoadingJob(), and GDCM_NAME_SPACE::DicomDir::Initialize().

char* GDCM_NAME_SPACE::Document::PtrBegBuffer [private]
 

Definition at line 261 of file gdcmDocument.h.

Referenced by FindDocEntryVR(), GetInt16(), and GetInt32().

Dict* GDCM_NAME_SPACE::Document::RefPubDict [protected]
 

Public dictionary used to parse this header.

Definition at line 238 of file gdcmDocument.h.

Referenced by GetPubDict(), and Initialize().

Dict* GDCM_NAME_SPACE::Document::RefShaDict [protected]
 

Optional "shadow dictionary" (private elements) used to parse this header.

Definition at line 241 of file gdcmDocument.h.

Referenced by GetShaDict(), Initialize(), and SetShaDict().

int GDCM_NAME_SPACE::Document::SwapCode [protected]
 

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 :

  • a 'Little Endian' image, read with a little endian processor will have a SwapCode= 1234 (the order is OK; nothing to do)
  • a 'Little Endian' image, read with a big endian procesor will have a SwapCode= 4321 (the order is wrong; int32 an int16 must be swapped) note : values 2143, 4321, 3412 remain for the ACR-NEMA time, and the well known 'Bad Big Endian' and 'Bad Little Endian' codes.

Definition at line 145 of file gdcmDocument.h.

Referenced by CheckSwap(), Document(), SwapDouble(), SwapLong(), SwapShort(), and SwitchByteSwapCode().

bool GDCM_NAME_SPACE::Document::UnexpectedEOF [private]
 

whether an unexpected EOF was encountered

Definition at line 268 of file gdcmDocument.h.

Referenced by Document(), and ParseSQ().

ListElements GDCM_NAME_SPACE::Document::UserAnonymizeList [protected]
 

User supplied list of elements to Anonymize.

Definition at line 166 of file gdcmDocument.h.

Referenced by GDCM_NAME_SPACE::File::AddAnonymizeElement(), GDCM_NAME_SPACE::File::AnonymizeFile(), and GDCM_NAME_SPACE::File::AnonymizeNoLoad().

ListElements GDCM_NAME_SPACE::Document::UserForceLoadList [protected]
 

User supplied list of elements to force Load.

Definition at line 169 of file gdcmDocument.h.

Referenced by AddForceLoadElement().


The documentation for this class was generated from the following files:
Generated on Fri Aug 24 13:01:43 2007 for gdcm by  doxygen 1.4.6