Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

gdcm::Document Class Reference

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

#include <gdcmDocument.h>

Inheritance diagram for gdcm::Document:

gdcm::ElementSet gdcm::DocEntrySet gdcm::Base gdcm::DicomDir gdcm::File List of all members.

Public Types

typedef std::list< ElementListElements

Public Member Functions

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.

virtual bool IsReadable ()
 This predicate, based on hopefully reasonable heuristics, decides whether or not the current Document was properly parsed and contains the mandatory information for being considered as a well formed and usable Dicom/Acr File.

bool IsDicomV3 ()
 Predicate for dicom version 3 file.

bool IsPapyrus ()
 Predicate for Papyrus file Dedicated to whomsoever it may concern.

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

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

std::string GetTransferSyntaxName ()
 Accesses the info from 0002,0010 : Transfer Syntax and TS.

int GetSwapCode ()
 'Swap code' accessor (see SwapCode )

uint16_t SwapShort (uint16_t)
 Swaps the bytes so they agree with the processor order.

uint32_t SwapLong (uint32_t)
 Swaps back the bytes of 4-byte long integer accordingly to processor order.

uint16_t UnswapShort (uint16_t a)
 Unswaps back the bytes of 2-bytes long integer so they agree with the processor order.

uint32_t UnswapLong (uint32_t a)
 Unswaps back the bytes of 4-byte long integer so they agree with the processor order.

const std::string & GetFileName () const
 Accessor to Filename.

void SetFileName (std::string const &fileName)
 Accessor to Filename.

std::ifstream * OpenFile ()
 Tries to open the file Document::Filename and checks the preamble when existing.

bool CloseFile ()
 closes the file

void WriteContent (std::ofstream *fp, FileType type)
 Writes in a file all the Header Entries (Dicom Elements).

virtual void LoadEntryBinArea (uint16_t group, uint16_t elem)
 Loads (from disk) the element content when a string is not suitable.

virtual void LoadEntryBinArea (BinEntry *entry)
 Loads (from disk) the element content when a string is not suitable.

void LoadDocEntrySafe (DocEntry *entry)
 Loads the element while preserving the current underlying file position indicator as opposed to LoadDocEntry that modifies it.

bool operator< (Document &document)
 Compares two documents, according to DicomDir rules.

virtual void Print (std::ostream &os=std::cout, std::string const &indent="")
 Prints the Header Entries (Dicom Elements) from the H Table.

bool AddEntry (DocEntry *Entry)
 add a new Dicom Element pointer to the H Table

bool RemoveEntry (DocEntry *EntryToRemove)
 Clear the hash table from given entry AND delete the entry.

bool RemoveEntryNoDestroy (DocEntry *EntryToRemove)
 Clear the hash table from given entry BUT keep the entry.

void ClearEntry ()
 delete all entries in the ElementSet

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.

virtual std::string GetEntryValue (uint16_t group, uint16_t elem)
 Get the "std::string representable" value of the Dicom entry.

virtual void * GetEntryBinArea (uint16_t group, uint16_t elem)
 Gets (from Header) a 'non string' element value.

virtual int GetEntryLength (uint16_t group, uint16_t elem)
 Searches within Header Entries (Dicom Elements) parsed with the public and private dictionaries for the value length of a given tag..

virtual std::string GetEntryVR (uint16_t group, uint16_t elem)
 Searches within Header Entries (Dicom Elements) parsed with the public [and private dictionaries] for the element value representation of a given tag.. Obtaining the VR (Value Representation) might be needed by caller to convert the string typed content to caller's native type (think of C++ vs Python). The VR is actually of a higher level of semantics than just the native C++ type.

ValEntryGetValEntry (uint16_t group, uint16_t elem)
 Same as Document::GetDocEntry except it only returns a result when the corresponding entry is of type ValEntry.

BinEntryGetBinEntry (uint16_t group, uint16_t elem)
 Same as Document::GetDocEntry except it only returns a result when the corresponding entry is of type BinEntry.

SeqEntryGetSeqEntry (uint16_t group, uint16_t elem)
 Same as Document::GetDocEntry except it only returns a result when the corresponding entry is of type SeqEntry.

bool SetValEntry (std::string const &content, uint16_t group, uint16_t elem)
 Accesses an existing DocEntry (i.e. a Dicom Element) through it's (group, element) and modifies it's content with the given value.

bool SetValEntry (std::string const &content, ValEntry *entry)
 Accesses an existing DocEntry (i.e. a Dicom Element) and modifies it's content with the given value.

bool SetBinEntry (uint8_t *content, int lgth, uint16_t group, uint16_t elem)
 Accesses an existing DocEntry (i.e. a Dicom Element) through it's (group, element) and modifies it's content with the given value.

bool SetBinEntry (uint8_t *content, int lgth, BinEntry *entry)
 Accesses an existing BinEntry (i.e. a Dicom Element) and modifies it's content with the given value.

ValEntryInsertValEntry (std::string const &value, uint16_t group, uint16_t elem, TagName const &vr=GDCM_UNKNOWN)
 Modifies the value of a given Doc Entry (Dicom Element) when it exists. Create it with the given value when unexistant.

BinEntryInsertBinEntry (uint8_t *binArea, int lgth, uint16_t group, uint16_t elem, TagName const &vr=GDCM_UNKNOWN)
 Modifies the value of a given Header Entry (Dicom Element) when it exists. Create it with the given value when unexistant. A copy of the binArea is made to be kept in the Document.

SeqEntryInsertSeqEntry (uint16_t group, uint16_t elem)
 Modifies the value of a given Doc Entry (Dicom Element) when it exists. Creates it when unexistant.

virtual bool CheckIfEntryExist (uint16_t group, uint16_t elem)
 Checks if a given Dicom Element exists within the H table.

ValEntryNewValEntry (uint16_t group, uint16_t elem, TagName const &vr=GDCM_UNKNOWN)
 Build a new Val Entry from all the low level arguments. Check for existence of dictionary entry, and build a default one when absent.

BinEntryNewBinEntry (uint16_t group, uint16_t elem, TagName const &vr=GDCM_UNKNOWN)
 Build a new Bin Entry from all the low level arguments. Check for existence of dictionary entry, and build a default one when absent.

SeqEntryNewSeqEntry (uint16_t group, uint16_t elem)
 Build a new Seq Entry from all the low level arguments. Check for existence of dictionary entry, and build a default one when absent.

DictEntryNewVirtualDictEntry (uint16_t group, uint16_t elem, TagName const &vr=GDCM_UNKNOWN, TagName const &vm=GDCM_UNKNOWN, TagName const &name=GDCM_UNKNOWN)
 Request a new virtual dict entry to the dict set.

void SetPrintLevel (int level)
 Sets the print level for the Dicom Header Elements.

int GetPrintLevel ()
 Gets the print level for the Dicom Entries.


Protected Member Functions

 Document ()
 This default constructor doesn't parse the file. You should then invoke Document::SetFileName and then the parsing.

 Document (std::string const &filename)
 constructor

virtual ~Document ()
 Canonical destructor.

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

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

void SkipBytes (uint32_t)
 skips bytes inside the source file

int ComputeGroup0002Length (FileType filetype)
 Re-computes the length of a ACR-NEMA/Dicom group from a DcmHeader.

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.

DictEntryGetDictEntry (uint16_t group, uint16_t elem, TagName const &vr)
 Searches [both] the public [and the shadow dictionary (when they exist)] for the presence of the DictEntry with given group and element, and create a new virtual DictEntry if necessary.


Protected Attributes

std::string Filename
 Refering underlying filename.

int SwapCode
 Swap code gives an information on the byte order of a supposed to be an int32, as it's read on disc (depending on the image Transfer Syntax *and* on the processor endianess) as opposed as it should in memory to be dealt as an int32. For instance :
  • 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 AnonymizeList
 List of element to Anonymize.

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


Static Protected Attributes

const unsigned int HEADER_LENGTH_TO_READ
 After opening the file, we read HEADER_LENGTH_TO_READ bytes.

const unsigned int MAX_SIZE_LOAD_ELEMENT_VALUE = 0xfff
 Elements whose value is longer than MAX_SIZE_LOAD_ELEMENT_VALUE are NOT loaded.

const unsigned int MAX_SIZE_PRINT_ELEMENT_VALUE = 0x7fffffff
 Elements whose value is longer than MAX_SIZE_PRINT_ELEMENT_VALUE are NOT printed.


Private Member Functions

void Initialize ()
 Loads all the needed Dictionaries.

void ParseDES (DocEntrySet *set, long offset, long l_max, bool delim_mode)
 Parses a DocEntrySet (Zero-level DocEntries or SQ Item DocEntries).

void ParseSQ (SeqEntry *seq, long offset, long l_max, bool delim_mode)
 Parses a Sequence ( SeqEntry after SeqEntry).

void LoadDocEntry (DocEntry *e)
 Loads the element content if its length doesn't exceed the value specified with Document::SetMaxSizeLoadEntry().

void FindDocEntryLength (DocEntry *e) throw ( FormatError )
 Find the value Length of the passed Header Entry.

uint32_t FindDocEntryLengthOBOrOW () throw ( FormatUnexpected )
 Find the Length till the next sequence delimiter.

std::string FindDocEntryVR ()
 Find the Value Representation of the current Dicom Element.

bool CheckDocEntryVR (VRKey k)
 Check the correspondance between the VR of the header entry and the taken VR. If they are different, the header entry is updated with the new VR.

std::string GetDocEntryValue (DocEntry *entry)
 Get the transformed value of the header entry. The VR value is used to define the transformation to operate on the value.

std::string GetDocEntryUnvalue (DocEntry *entry)
 Get the reverse transformed value of the header entry. The VR value is used to define the reverse transformation to operate on the value.

void SkipDocEntry (DocEntry *entry)
 Skip a given Header Entry.

void SkipToNextDocEntry (DocEntry *entry)
 Skips to the beginning of the next Header Entry.

void FixDocEntryFoundLength (DocEntry *entry, uint32_t l)
 When the length of an element value is obviously wrong (because the parser went Jabberwocky) one can hope improving things by applying some heuristics.

bool IsDocEntryAnInteger (DocEntry *entry)
 Apply some heuristics to predict whether the considered element value contains/represents an integer or not.

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

void SwitchByteSwapCode ()
 Change the Byte Swap code.

void SetMaxSizeLoadEntry (long)
 during parsing, Header Elements too long are not loaded in memory

void SetMaxSizePrintEntry (long)
 Header Elements too long will not be printed.

DocEntryReadNextDocEntry ()
 Read the next tag but WITHOUT loading it's value (read the 'Group Number', the 'Element Number', gets the Dict Entry gets the VR, gets the length, gets the offset value).

void HandleBrokenEndian (uint16_t &group, uint16_t &elem)
 Handle broken private tag from Philips NTSCAN where the endianess is being switch to BigEndian for no apparent reason.

void HandleOutOfGroup0002 (uint16_t &group, uint16_t &elem)
 Group 0002 is always coded Little Endian whatever Transfer Syntax is.


Private Attributes

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).

uint32_t MaxSizePrintEntry
 Size threshold above which an element value will NOT be *printed* in order no to polute the screen output. By default, this upper bound is fixed to 64 bytes.


Detailed Description

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

Definition at line 43 of file gdcmDocument.h.


Member Typedef Documentation

typedef std::list<Element> gdcm::Document::ListElements
 

Definition at line 47 of file gdcmDocument.h.


Constructor & Destructor Documentation

gdcm::Document::Document  )  [protected]
 

This default constructor doesn't parse the file. You should then invoke Document::SetFileName and then the parsing.

Definition at line 157 of file gdcmDocument.cxx.

References gdcm::ExplicitVR, Filetype, Fp, Group0002Parsed, Initialize(), MAX_SIZE_LOAD_ELEMENT_VALUE, SetMaxSizeLoadEntry(), and SwapCode.

00158          :ElementSet(-1)
00159 {
00160    Fp = 0;
00161 
00162    SetMaxSizeLoadEntry(MAX_SIZE_LOAD_ELEMENT_VALUE);
00163    Initialize();
00164    SwapCode = 1234;
00165    Filetype = ExplicitVR;
00166    Group0002Parsed = false;
00167 }

gdcm::Document::Document std::string const &  filename  )  [protected]
 

constructor

Parameters:
filename 'Document' (File or DicomDir) to be opened for parsing

FIXME FIXME FIXME The tags refered by the three following lines used to be CORRECTLY defined as having an US Value Representation in the public dictionary. BUT the semantics implied by the three following lines state that the corresponding tag contents are in fact the ones of a BinEntry. In order to fix things "Quick and Dirty" the dictionary was altered on PURPOSE but now contains a WRONG value. In order to fix things and restore the dictionary to its correct value, one needs to decided of the semantics by deciding whether the following tags are either:

  • 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 61 of file gdcmDocument.cxx.

References gdcm::ACR_LIBIDO, CheckSwap(), CloseFile(), Filetype, Fp, gdcmWarningMacro, gdcm::DocEntrySet::GetEntryValue(), Group0002Parsed, Initialize(), LoadEntryBinArea(), MAX_SIZE_LOAD_ELEMENT_VALUE, OpenFile(), ParseDES(), SetMaxSizeLoadEntry(), and gdcm::DocEntrySet::SetValEntry().

00062          :ElementSet(-1)
00063 {
00064    SetMaxSizeLoadEntry(MAX_SIZE_LOAD_ELEMENT_VALUE); 
00065    Filename = filename;
00066    Initialize();
00067 
00068    Fp = 0;
00069    if ( !OpenFile() )
00070    {
00071       return;
00072    }
00073 
00074    Group0002Parsed = false;
00075 
00076    gdcmWarningMacro( "Starting parsing of file: " << Filename.c_str());
00077 
00078    Fp->seekg(0, std::ios::end);
00079    long lgt = Fp->tellg();
00080            
00081    Fp->seekg(0, std::ios::beg);
00082 
00083    CheckSwap();
00084    long beg = Fp->tellg();
00085    lgt -= beg;
00086    
00087    ParseDES( this, beg, lgt, false); // Loading is done during parsing
00088 
00089    Fp->seekg( 0,  std::ios::beg);
00090    
00091    // Load 'non string' values
00092       
00093    std::string PhotometricInterpretation = GetEntryValue(0x0028,0x0004);   
00094    if( PhotometricInterpretation == "PALETTE COLOR " )
00095    {
00096       LoadEntryBinArea(0x0028,0x1200);  // gray LUT   
00112       LoadEntryBinArea(0x0028,0x1201);  // R    LUT
00113       LoadEntryBinArea(0x0028,0x1202);  // G    LUT
00114       LoadEntryBinArea(0x0028,0x1203);  // B    LUT
00115       
00116       // Segmented Red   Palette Color LUT Data
00117       LoadEntryBinArea(0x0028,0x1221);
00118       // Segmented Green Palette Color LUT Data
00119       LoadEntryBinArea(0x0028,0x1222);
00120       // Segmented Blue  Palette Color LUT Data
00121       LoadEntryBinArea(0x0028,0x1223);
00122    } 
00123    //FIXME later : how to use it?
00124    LoadEntryBinArea(0x0028,0x3006);  //LUT Data (CTX dependent) 
00125 
00126    CloseFile(); 
00127   
00128    // ----------------------------
00129    // Specific code to allow gdcm to read ACR-LibIDO formated images
00130    // Note: ACR-LibIDO is an extension of the ACR standard that was
00131    //       used at CREATIS. For the time being (say a couple years)
00132    //       we keep this kludge to allow a smooth move to gdcm for
00133    //       CREATIS developpers (sorry folks).
00134    //
00135    // if recognition code tells us we deal with a LibIDO image
00136    // we switch lineNumber and columnNumber
00137    //
00138    std::string RecCode;
00139    RecCode = GetEntryValue(0x0008, 0x0010); // recognition code (RET)
00140    if (RecCode == "ACRNEMA_LIBIDO_1.1" ||
00141        RecCode == "CANRME_AILIBOD1_1." )  // for brain-damaged softwares
00142                                           // with "little-endian strings"
00143    {
00144          Filetype = ACR_LIBIDO; 
00145          std::string rows    = GetEntryValue(0x0028, 0x0010);
00146          std::string columns = GetEntryValue(0x0028, 0x0011);
00147          SetValEntry(columns, 0x0028, 0x0010);
00148          SetValEntry(rows   , 0x0028, 0x0011);
00149    }
00150    // --- End of ACR-LibIDO kludge --- 
00151 }

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

Canonical destructor.

Definition at line 172 of file gdcmDocument.cxx.

References RefPubDict, and RefShaDict.

00173 {
00174    RefPubDict = NULL;
00175    RefShaDict = NULL;
00176 }


Member Function Documentation

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

add a new Dicom Element pointer to the H Table

Parameters:
newEntry entry to add

Implements gdcm::DocEntrySet.

Definition at line 69 of file gdcmElementSet.cxx.

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

Referenced by gdcm::File::File(), gdcm::DocEntryArchive::Push(), and gdcm::DocEntryArchive::Restore().

00070 {
00071    const TagKey &key = newEntry->GetKey();
00072 
00073    if( TagHT.count(key) == 1 )
00074    {
00075       gdcmWarningMacro( "Key already present: " << key.c_str());
00076       return false;
00077    }
00078    else
00079    {
00080       TagHT.insert(TagDocEntryHT::value_type(newEntry->GetKey(), newEntry));
00081       return true;
00082    }
00083 }

bool gdcm::Document::CheckDocEntryVR 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 of if the VR isn't referenced otherwise, it returns true

Definition at line 1439 of file gdcmDocument.cxx.

References gdcm::VRKey.

Referenced by FindDocEntryVR().

01440 {
01441    if ( !Global::GetVR()->IsValidVR(vr) )
01442       return false;
01443 
01444    return true; 
01445 }

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

Checks if a given Dicom Element exists within the H table.

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

Definition at line 434 of file gdcmDocEntrySet.cxx.

References gdcm::DocEntrySet::GetDocEntry().

00435 {
00436    return GetDocEntry(group,elem)!=NULL;
00437 }

bool gdcm::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 1725 of file gdcmDocument.cxx.

References gdcm::ACR, gdcm::ExplicitVR, Filetype, Fp, gdcmWarningMacro, gdcm::ImplicitVR, SwapCode, and gdcm::Unknown.

Referenced by Document().

01726 {
01727    // The only guaranted way of finding the swap code is to find a
01728    // group tag since we know it's length has to be of four bytes i.e.
01729    // 0x00000004. Finding the swap code in then straigthforward. Trouble
01730    // occurs when we can't find such group...
01731    
01732    uint32_t  x = 4;  // x : for ntohs
01733    bool net2host; // true when HostByteOrder is the same as NetworkByteOrder
01734    uint32_t  s32;
01735    uint16_t  s16;
01736        
01737    char deb[256];
01738     
01739    // First, compare HostByteOrder and NetworkByteOrder in order to
01740    // determine if we shall need to swap bytes (i.e. the Endian type).
01741    if ( x == ntohs(x) )
01742    {
01743       net2host = true;
01744    }
01745    else
01746    {
01747       net2host = false;
01748    }
01749          
01750    // The easiest case is the one of a 'true' DICOM header, we just have
01751    // to look for the string "DICM" inside the file preamble.
01752    Fp->read(deb, 256);
01753    
01754    char *entCur = deb + 128;
01755    if( memcmp(entCur, "DICM", (size_t)4) == 0 )
01756    {
01757       gdcmWarningMacro( "Looks like DICOM Version3 (preamble + DCM)" );
01758       
01759       // Group 0002 should always be VR, and the first element 0000
01760       // Let's be carefull (so many wrong headers ...)
01761       // and determine the value representation (VR) : 
01762       // Let's skip to the first element (0002,0000) and check there if we find
01763       // "UL"  - or "OB" if the 1st one is (0002,0001) -,
01764       // in which case we (almost) know it is explicit VR.
01765       // WARNING: if it happens to be implicit VR then what we will read
01766       // is the length of the group. If this ascii representation of this
01767       // length happens to be "UL" then we shall believe it is explicit VR.
01768       // We need to skip :
01769       // * the 128 bytes of File Preamble (often padded with zeroes),
01770       // * the 4 bytes of "DICM" string,
01771       // * the 4 bytes of the first tag (0002, 0000),or (0002, 0001)
01772       // i.e. a total of  136 bytes.
01773       entCur = deb + 136;
01774      
01775       // group 0x0002 *is always* Explicit VR Sometimes ,
01776       // even if elem 0002,0010 (Transfer Syntax) tells us the file is
01777       // *Implicit* VR  (see former 'gdcmData/icone.dcm')
01778       
01779       if( memcmp(entCur, "UL", (size_t)2) == 0 ||
01780           memcmp(entCur, "OB", (size_t)2) == 0 ||
01781           memcmp(entCur, "UI", (size_t)2) == 0 ||
01782           memcmp(entCur, "CS", (size_t)2) == 0 )  // CS, to remove later
01783                                                   // when Write DCM *adds*
01784       // FIXME
01785       // Use Document::dicom_vr to test all the possibilities
01786       // instead of just checking for UL, OB and UI !? group 0000 
01787       {
01788          Filetype = ExplicitVR;
01789          gdcmWarningMacro( "Group 0002 : Explicit Value Representation");
01790       } 
01791       else 
01792       {
01793          Filetype = ImplicitVR;
01794          gdcmWarningMacro( "Group 0002 :Not an explicit Value Representation;"
01795                         << "Looks like a bugged Header!");
01796       }
01797       
01798       if ( net2host )
01799       {
01800          SwapCode = 4321;
01801          gdcmWarningMacro( "HostByteOrder != NetworkByteOrder");
01802       }
01803       else 
01804       {
01805          SwapCode = 1234;
01806          gdcmWarningMacro( "HostByteOrder = NetworkByteOrder");
01807       }
01808       
01809       // Position the file position indicator at first tag 
01810       // (i.e. after the file preamble and the "DICM" string).
01811       Fp->seekg(0, std::ios::beg);
01812       Fp->seekg ( 132L, std::ios::beg);
01813       return true;
01814    } // End of DicomV3
01815 
01816    // Alas, this is not a DicomV3 file and whatever happens there is no file
01817    // preamble. We can reset the file position indicator to where the data
01818    // is (i.e. the beginning of the file).
01819    gdcmWarningMacro( "Not a DICOM Version3 file");
01820    Fp->seekg(0, std::ios::beg);
01821 
01822    // Our next best chance would be to be considering a 'clean' ACR/NEMA file.
01823    // By clean we mean that the length of the first tag is written down.
01824    // If this is the case and since the length of the first group HAS to be
01825    // four (bytes), then determining the proper swap code is straightforward.
01826 
01827    entCur = deb + 4;
01828    // We assume the array of char we are considering contains the binary
01829    // representation of a 32 bits integer. Hence the following dirty
01830    // trick :
01831    s32 = *((uint32_t *)(entCur));
01832 
01833    switch( s32 )
01834    {
01835       case 0x00040000 :
01836          SwapCode = 3412;
01837          Filetype = ACR;
01838          return true;
01839       case 0x04000000 :
01840          SwapCode = 4321;
01841          Filetype = ACR;
01842          return true;
01843       case 0x00000400 :
01844          SwapCode = 2143;
01845          Filetype = ACR;
01846          return true;
01847       case 0x00000004 :
01848          SwapCode = 1234;
01849          Filetype = ACR;
01850          return true;
01851       default :
01852          // We are out of luck. It is not a DicomV3 nor a 'clean' ACR/NEMA file.
01853          // It is time for despaired wild guesses. 
01854          // So, let's check if this file wouldn't happen to be 'dirty' ACR/NEMA,
01855          //  i.e. the 'group length' element is not present :     
01856          
01857          //  check the supposed-to-be 'group number'
01858          //  in ( 0x0001 .. 0x0008 )
01859          //  to determine ' SwapCode' value .
01860          //  Only 0 or 4321 will be possible 
01861          //  (no oportunity to check for the formerly well known
01862          //  ACR-NEMA 'Bad Big Endian' or 'Bad Little Endian' 
01863          //  if unsuccessfull (i.e. neither 0x0002 nor 0x0200 etc -3, 4, ..., 8-) 
01864          //  the file IS NOT ACR-NEMA nor DICOM V3
01865          //  Find a trick to tell it the caller...
01866       
01867          s16 = *((uint16_t *)(deb));
01868       
01869          switch ( s16 )
01870          {
01871             case 0x0001 :
01872             case 0x0002 :
01873             case 0x0003 :
01874             case 0x0004 :
01875             case 0x0005 :
01876             case 0x0006 :
01877             case 0x0007 :
01878             case 0x0008 :
01879                SwapCode = 1234;
01880                Filetype = ACR;
01881                return true;
01882             case 0x0100 :
01883             case 0x0200 :
01884             case 0x0300 :
01885             case 0x0400 :
01886             case 0x0500 :
01887             case 0x0600 :
01888             case 0x0700 :
01889             case 0x0800 :
01890                SwapCode = 4321;
01891                Filetype = ACR;
01892                return true;
01893             default :
01894                gdcmWarningMacro( "ACR/NEMA unfound swap info (Really hopeless !)");
01895                Filetype = Unknown;
01896                return false;
01897          }
01898    }
01899 }

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

delete all entries in the ElementSet

Implements gdcm::DocEntrySet.

Definition at line 125 of file gdcmElementSet.cxx.

References gdcm::ElementSet::TagHT.

Referenced by gdcm::DicomDir::CreateDicomDir(), gdcm::DicomDir::SetElements(), and gdcm::ElementSet::~ElementSet().

00126 {
00127    for(TagDocEntryHT::iterator cc = TagHT.begin();cc != TagHT.end(); ++cc)
00128    {
00129       if ( cc->second )
00130       {
00131          delete cc->second;
00132       }
00133    }
00134    TagHT.clear();
00135 }

bool gdcm::Document::CloseFile  ) 
 

closes the file

Returns:
TRUE if the close was successfull

Definition at line 464 of file gdcmDocument.cxx.

References Fp.

Referenced by Document(), gdcm::File::File(), gdcm::FileHelper::GetRaw(), LoadEntryBinArea(), and OpenFile().

00465 {
00466    if( Fp )
00467    {
00468       Fp->close();
00469       delete Fp;
00470       Fp = 0;
00471    }
00472    return true; //FIXME how do we detect a non-closed ifstream ?
00473 }

int gdcm::Document::ComputeGroup0002Length FileType  filetype  )  [protected]
 

Re-computes the length of a ACR-NEMA/Dicom group from a DcmHeader.

Parameters:
filetype Type of the File to be written

Definition at line 717 of file gdcmDocument.cxx.

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

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

00718 {
00719    uint16_t gr;
00720    std::string vr;
00721    
00722    int groupLength = 0;
00723    bool found0002 = false;   
00724   
00725    // for each zero-level Tag in the DCM Header
00726    DocEntry *entry = GetFirstEntry();
00727    while( entry )
00728    {
00729       gr = entry->GetGroup();
00730 
00731       if( gr == 0x0002 )
00732       {
00733          found0002 = true;
00734 
00735          if( entry->GetElement() != 0x0000 )
00736          {
00737             vr = entry->GetVR();
00738  
00739             if( filetype == ExplicitVR )
00740             {
00741                if ( (vr == "OB") || (vr == "OW") || (vr == "SQ") ) 
00742                {
00743                   // explicit VR AND OB, OW, SQ : 4 more bytes
00744                   groupLength +=  4;
00745                }
00746             }
00747             groupLength += 2 + 2 + 4 + entry->GetLength();   
00748          }
00749       }
00750       else if (found0002 )
00751          break;
00752 
00753       entry = GetNextEntry();
00754    }
00755    return groupLength; 
00756 }

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

Find the value Length of the passed Header Entry.

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

Definition at line 1201 of file gdcmDocument.cxx.

References gdcm::ExplicitVR.

Referenced by ReadNextDocEntry().

01203 {
01204    std::string  vr  = entry->GetVR();
01205    uint16_t length16;       
01206    
01207    if ( Filetype == ExplicitVR && !entry->IsImplicitVR() ) 
01208    {
01209       if ( vr == "OB" || vr == "OW" || vr == "SQ" || vr == "UN" ) 
01210       {
01211          // The following reserved two bytes (see PS 3.5-2003, section
01212          // "7.1.2 Data element structure with explicit vr", p 27) must be
01213          // skipped before proceeding on reading the length on 4 bytes.
01214          Fp->seekg( 2L, std::ios::cur);
01215          uint32_t length32 = ReadInt32();
01216 
01217          if ( (vr == "OB" || vr == "OW") && length32 == 0xffffffff ) 
01218          {
01219             uint32_t lengthOB;
01220             try 
01221             {
01222                lengthOB = FindDocEntryLengthOBOrOW();
01223             }
01224             catch ( FormatUnexpected )
01225             {
01226                // Computing the length failed (this happens with broken
01227                // files like gdcm-JPEG-LossLess3a.dcm). We still have a
01228                // chance to get the pixels by deciding the element goes
01229                // until the end of the file. Hence we artificially fix the
01230                // the length and proceed.
01231                long currentPosition = Fp->tellg();
01232                Fp->seekg(0L,std::ios::end);
01233 
01234                long lengthUntilEOF = (long)(Fp->tellg())-currentPosition;
01235                Fp->seekg(currentPosition, std::ios::beg);
01236 
01237                entry->SetReadLength(lengthUntilEOF);
01238                entry->SetLength(lengthUntilEOF);
01239                return;
01240             }
01241             entry->SetReadLength(lengthOB);
01242             entry->SetLength(lengthOB);
01243             return;
01244          }
01245          FixDocEntryFoundLength(entry, length32); 
01246          return;
01247       }
01248 
01249       // Length is encoded on 2 bytes.
01250       length16 = ReadInt16();
01251 
01252       // FIXME : This heuristic supposes that the first group following
01253       //         group 0002 *has* and element 0000.
01254       // BUT ... Element 0000 is optionnal :-(
01255 
01256 
01257    // Fixed using : HandleOutOfGroup0002()
01258    //              (first hereafter strategy ...)
01259       
01260       // We can tell the current file is encoded in big endian (like
01261       // Data/US-RGB-8-epicard) when we find the "Transfer Syntax" tag
01262       // and it's value is the one of the encoding of a big endian file.
01263       // In order to deal with such big endian encoded files, we have
01264       // (at least) two strategies:
01265       // * when we load the "Transfer Syntax" tag with value of big endian
01266       //   encoding, we raise the proper flags. Then we wait for the end
01267       //   of the META group (0x0002) among which is "Transfer Syntax",
01268       //   before switching the swap code to big endian. We have to postpone
01269       //   the switching of the swap code since the META group is fully encoded
01270       //   in little endian, and big endian coding only starts at the next
01271       //   group. The corresponding code can be hard to analyse and adds
01272       //   many additional unnecessary tests for regular tags.
01273       // * the second strategy consists in waiting for trouble, that shall
01274       //   appear when we find the first group with big endian encoding. This
01275       //   is easy to detect since the length of a "Group Length" tag (the
01276       //   ones with zero as element number) has to be of 4 (0x0004). When we
01277       //   encounter 1024 (0x0400) chances are the encoding changed and we
01278       //   found a group with big endian encoding.
01279       //---> Unfortunately, element 0000 is optional.
01280       //---> This will not work when missing!
01281       // We shall use this second strategy. In order to make sure that we
01282       // can interpret the presence of an apparently big endian encoded
01283       // length of a "Group Length" without committing a big mistake, we
01284       // add an additional check: we look in the already parsed elements
01285       // for the presence of a "Transfer Syntax" whose value has to be "big
01286       // endian encoding". When this is the case, chances are we have got our
01287       // hands on a big endian encoded file: we switch the swap code to
01288       // big endian and proceed...
01289 
01290 //      if ( element  == 0x0000 && length16 == 0x0400 ) 
01291 //      {
01292 //         std::string ts = GetTransferSyntax();
01293 //         if ( Global::GetTS()->GetSpecialTransferSyntax(ts) 
01294 //                != TS::ExplicitVRBigEndian ) 
01295 //         {
01296 //            throw FormatError( "Document::FindDocEntryLength()",
01297 //                               " not explicit VR." );
01298 //           return;
01299 //        }
01300 //        length16 = 4;
01301 //        SwitchByteSwapCode();
01302 //
01303 //         // Restore the unproperly loaded values i.e. the group, the element
01304 //         // and the dictionary entry depending on them.
01305 //         uint16_t correctGroup = SwapShort( entry->GetGroup() );
01306 //         uint16_t correctElem  = SwapShort( entry->GetElement() );
01307 //         DictEntry *newTag = GetDictEntry( correctGroup, correctElem );
01308 //         if ( !newTag )
01309 //         {
01310 //            // This correct tag is not in the dictionary. Create a new one.
01311 //            newTag = NewVirtualDictEntry(correctGroup, correctElem);
01312 //         }
01313 //         // FIXME this can create a memory leaks on the old entry that be
01314 //         // left unreferenced.
01315 //         entry->SetDictEntry( newTag );
01316 //      }
01317   
01318       // 0xffff means that we deal with 'No Length' Sequence 
01319       //        or 'No Length' SQItem
01320       if ( length16 == 0xffff) 
01321       {           
01322          length16 = 0;
01323       }
01324       FixDocEntryFoundLength( entry, (uint32_t)length16 );
01325       return;
01326    }
01327    else
01328    {
01329       // Either implicit VR or a non DICOM conformal (see note below) explicit
01330       // VR that ommited the VR of (at least) this element. Farts happen.
01331       // [Note: according to the part 5, PS 3.5-2001, section 7.1 p25
01332       // on Data elements "Implicit and Explicit VR Data Elements shall
01333       // not coexist in a Data Set and Data Sets nested within it".]
01334       // Length is on 4 bytes.
01335 
01336      // Well ... group 0002 is always coded in 'Explicit VR Litle Endian'
01337      // even if Transfer Syntax is 'Implicit VR ...' 
01338       
01339       FixDocEntryFoundLength( entry, ReadInt32() );
01340       return;
01341    }
01342 }

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

Find the Length till the next sequence delimiter.

Warning:
NOT end user intended method !
Returns:

Definition at line 1349 of file gdcmDocument.cxx.

References gdcmWarningMacro.

01351 {
01352    // See PS 3.5-2001, section A.4 p. 49 on encapsulation of encoded pixel data.
01353    long positionOnEntry = Fp->tellg();
01354    bool foundSequenceDelimiter = false;
01355    uint32_t totalLength = 0;
01356 
01357    while ( !foundSequenceDelimiter )
01358    {
01359       uint16_t group;
01360       uint16_t elem;
01361       try
01362       {
01363          group = ReadInt16();
01364          elem  = ReadInt16();   
01365       }
01366       catch ( FormatError )
01367       {
01368          throw FormatError("Unexpected end of file encountered during ",
01369                            "Document::FindDocEntryLengthOBOrOW()");
01370       }
01371       // We have to decount the group and element we just read
01372       totalLength += 4;     
01373       if ( group != 0xfffe || ( ( elem != 0xe0dd ) && ( elem != 0xe000 ) ) )
01374       {
01375          long filePosition = Fp->tellg();
01376          gdcmWarningMacro( "Neither an Item tag nor a Sequence delimiter tag on :" 
01377            << std::hex << group << " , " << elem 
01378            << ") -before- position x(" << filePosition << ")" );
01379   
01380          Fp->seekg(positionOnEntry, std::ios::beg);
01381          throw FormatUnexpected( "Neither an Item tag nor a Sequence delimiter tag.");
01382       }
01383       if ( elem == 0xe0dd )
01384       {
01385          foundSequenceDelimiter = true;
01386       }
01387       uint32_t itemLength = ReadInt32();
01388       // We add 4 bytes since we just read the ItemLength with ReadInt32
01389       totalLength += itemLength + 4;
01390       SkipBytes(itemLength);
01391       
01392       if ( foundSequenceDelimiter )
01393       {
01394          break;
01395       }
01396    }
01397    Fp->seekg( positionOnEntry, std::ios::beg);
01398    return totalLength;
01399 }

std::string gdcm::Document::FindDocEntryVR  )  [private]
 

Find the Value Representation of the current Dicom Element.

Returns:
Value Representation of the current Entry

Definition at line 1405 of file gdcmDocument.cxx.

References CheckDocEntryVR(), gdcm::ExplicitVR, Filetype, Fp, and gdcm::GDCM_UNKNOWN.

Referenced by ReadNextDocEntry().

01406 {
01407    if ( Filetype != ExplicitVR )
01408       return GDCM_UNKNOWN;
01409 
01410    long positionOnEntry = Fp->tellg();
01411    // Warning: we believe this is explicit VR (Value Representation) because
01412    // we used a heuristic that found "UL" in the first tag. Alas this
01413    // doesn't guarantee that all the tags will be in explicit VR. In some
01414    // cases (see e-film filtered files) one finds implicit VR tags mixed
01415    // within an explicit VR file. Hence we make sure the present tag
01416    // is in explicit VR and try to fix things if it happens not to be
01417    // the case.
01418 
01419    char vr[3];
01420    Fp->read (vr, (size_t)2);
01421    vr[2] = 0;
01422 
01423    if( !CheckDocEntryVR(vr) )
01424    {
01425       Fp->seekg(positionOnEntry, std::ios::beg);
01426       return GDCM_UNKNOWN;
01427    }
01428    return vr;
01429 }

void gdcm::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

Todo:
a bug is to be fixed !?

a bug is to be fixed !?

Definition at line 1606 of file gdcmDocument.cxx.

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

01608 {
01609    entry->SetReadLength( foundLength ); // will be updated only if a bug is found        
01610    if ( foundLength == 0xffffffff)
01611    {
01612       foundLength = 0;
01613    }
01614    
01615    uint16_t gr   = entry->GetGroup();
01616    uint16_t elem = entry->GetElement(); 
01617      
01618    if ( foundLength % 2)
01619    {
01620       gdcmWarningMacro( "Warning : Tag with uneven length " << foundLength 
01621         <<  " in x(" << std::hex << gr << "," << elem <<")");
01622    }
01623       
01625    // Allthough not recent many such GE corrupted images are still present
01626    // on Creatis hard disks. Hence this fix shall remain when such images
01627    // are no longer in use (we are talking a few years, here)...
01628    // Note: XMedCom probably uses such a trick since it is able to read
01629    //       those pesky GE images ...
01630    if ( foundLength == 13)
01631    {
01632       // Only happens for this length !
01633       if ( gr != 0x0008 || ( elem != 0x0070 && elem != 0x0080 ) )
01634       {
01635          foundLength = 10;
01636          entry->SetReadLength(10); 
01637       }
01638    }
01639 
01641    // Occurence of such images is quite low (unless one leaves close to a
01642    // 'Leonardo' source. Hence, one might consider commenting out the
01643    // following fix on efficiency reasons.
01644    else if ( gr   == 0x0009 && ( elem == 0x1113 || elem == 0x1114 ) )
01645    {
01646       foundLength = 4;
01647       entry->SetReadLength(4); 
01648    } 
01649  
01650    else if ( entry->GetVR() == "SQ" )
01651    {
01652       foundLength = 0;      // ReadLength is unchanged 
01653    } 
01654     
01656    // "fffe|xxxx" which is just a marker. Delimiters length should not be
01657    // taken into account.
01658    else if( gr == 0xfffe )
01659    {    
01660      // According to the norm, fffe|0000 shouldn't exist. BUT the Philips
01661      // image gdcmData/gdcm-MR-PHILIPS-16-Multi-Seq.dcm happens to
01662      // causes extra troubles...
01663      if( entry->GetElement() != 0x0000 )
01664      {
01665         foundLength = 0;
01666      }
01667    }            
01668    entry->SetLength(foundLength);
01669 }

BinEntry * gdcm::DocEntrySet::GetBinEntry uint16_t  group,
uint16_t  elem
[inherited]
 

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

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

Definition at line 127 of file gdcmDocEntrySet.cxx.

References gdcmWarningMacro, and gdcm::DocEntrySet::GetDocEntry().

Referenced by gdcm::DocEntrySet::GetEntryBinArea(), and gdcm::DocEntrySet::SetBinEntry().

00128 {
00129    DocEntry *currentEntry = GetDocEntry(group, elem);
00130    if ( !currentEntry )
00131    {
00132       gdcmWarningMacro( "No corresponding BinEntry " << std::hex << group <<
00133                          "," << elem);
00134       return NULL;
00135    }
00136 
00137    return dynamic_cast<BinEntry*>(currentEntry);
00138 }

DictEntry * gdcm::DocEntrySet::GetDictEntry uint16_t  group,
uint16_t  elem,
TagName const &  vr
[protected, inherited]
 

Searches [both] the public [and the shadow dictionary (when they exist)] for the presence of the DictEntry with given group and element, and create a new virtual DictEntry if necessary.

Parameters:
group group number of the searched DictEntry
elem element number of the searched DictEntry
vr Value Representation to use, if necessary
Returns:
Corresponding DictEntry when it exists, NULL otherwise.

Definition at line 558 of file gdcmDocEntrySet.cxx.

References gdcm::GDCM_UNKNOWN, gdcm::DocEntrySet::GetDictEntry(), gdcm::DictEntry::GetName(), gdcm::DictEntry::GetVR(), gdcm::DocEntrySet::NewVirtualDictEntry(), and gdcm::TagName.

00560 {
00561    DictEntry *dictEntry = GetDictEntry(group,elem);
00562    DictEntry *goodEntry = dictEntry;
00563    std::string goodVR = vr;
00564 
00565    if (elem == 0x0000) goodVR="UL";
00566 
00567    if ( goodEntry )
00568    {
00569       if ( goodVR != goodEntry->GetVR()
00570         && goodVR != GDCM_UNKNOWN )
00571       {
00572          goodEntry = NULL;
00573       }
00574    }
00575 
00576    // Create a new virtual DictEntry if necessary
00577    if (!goodEntry)
00578    {
00579       if (dictEntry)
00580       {
00581          goodEntry = NewVirtualDictEntry(group, elem, goodVR, "FIXME", 
00582                                          dictEntry->GetName() );
00583       }
00584       else
00585       {
00586          goodEntry = NewVirtualDictEntry(group, elem, goodVR);
00587       }
00588    }
00589    return goodEntry;
00590 }

DictEntry * gdcm::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.

Parameters:
group group number of the searched DictEntry
elem element number of the searched DictEntry
Returns:
Corresponding DictEntry when it exists, NULL otherwise.

Definition at line 534 of file gdcmDocEntrySet.cxx.

References gdcmWarningMacro, and gdcm::Dict::GetEntry().

Referenced by gdcm::DocEntrySet::GetDictEntry(), gdcm::DocEntrySet::NewBinEntry(), gdcm::DocEntrySet::NewSeqEntry(), gdcm::DocEntrySet::NewValEntry(), and ReadNextDocEntry().

00535 {
00536    DictEntry *found = 0;
00537    Dict *pubDict = Global::GetDicts()->GetDefaultPubDict();
00538    if (!pubDict) 
00539    {
00540       gdcmWarningMacro( "We SHOULD have a default dictionary");
00541    }
00542    else
00543    {
00544       found = pubDict->GetEntry(group, elem);  
00545    }
00546    return found;
00547 }

DocEntry * gdcm::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::DocEntrySet.

Definition at line 172 of file gdcmElementSet.cxx.

References gdcm::ElementSet::TagHT, and gdcm::TagKey.

Referenced by gdcm::File::AnonymizeFile(), gdcm::File::AnonymizeNoLoad(), gdcm::FileHelper::CopyBinEntry(), gdcm::FileHelper::CopyValEntry(), gdcm::DicomDir::CreateDicomDir(), gdcm::DicomDir::DicomDir(), gdcm::File::File(), gdcm::File::GetPixelAreaLength(), gdcm::File::GetPixelOffset(), GetTransferSyntax(), gdcm::File::HasLUT(), IsDicomV3(), IsPapyrus(), gdcm::File::IsReadable(), LoadEntryBinArea(), gdcm::DocEntryArchive::Push(), gdcm::DocEntryArchive::Restore(), gdcm::FileHelper::SetWriteToLibido(), gdcm::FileHelper::SetWriteToNoLibido(), and gdcm::File::Write().

00173 {
00174    TagKey key = DictEntry::TranslateToKey(group, elem);
00175    TagDocEntryHT::iterator it = TagHT.find(key);
00176 
00177    if ( it!=TagHT.end() )
00178       return it->second;
00179    return NULL;
00180 }

std::string gdcm::Document::GetDocEntryUnvalue DocEntry entry  )  [private]
 

Get the reverse transformed value of the header entry. The VR value is used to define the reverse transformation to operate on the value.

Warning:
NOT end user intended method !
Parameters:
entry Entry to reverse transform
Returns:
Reverse transformed entry value

Definition at line 1529 of file gdcmDocument.cxx.

References gdcm::DocEntry::GetVR(), IsDocEntryAnInteger(), and gdcm::DocEntry::IsImplicitVR().

01530 {
01531    if ( IsDocEntryAnInteger(entry) && entry->IsImplicitVR() )
01532    {
01533       std::string vr = entry->GetVR();
01534       std::vector<std::string> tokens;
01535       std::ostringstream s;
01536 
01537       if ( vr == "US" || vr == "SS" ) 
01538       {
01539          uint16_t newInt16;
01540 
01541          tokens.erase( tokens.begin(), tokens.end()); // clean any previous value
01542          Util::Tokenize (((ValEntry *)entry)->GetValue(), tokens, "\\");
01543          for (unsigned int i=0; i<tokens.size(); i++) 
01544          {
01545             newInt16 = atoi(tokens[i].c_str());
01546             s << (  newInt16        & 0xFF ) 
01547               << (( newInt16 >> 8 ) & 0xFF );
01548          }
01549          tokens.clear();
01550       }
01551       if ( vr == "UL" || vr == "SL")
01552       {
01553          uint32_t newInt32;
01554 
01555          tokens.erase(tokens.begin(),tokens.end()); // clean any previous value
01556          Util::Tokenize (((ValEntry *)entry)->GetValue(), tokens, "\\");
01557          for (unsigned int i=0; i<tokens.size();i++) 
01558          {
01559             newInt32 = atoi(tokens[i].c_str());
01560             s << (char)(  newInt32         & 0xFF ) 
01561               << (char)(( newInt32 >>  8 ) & 0xFF )
01562               << (char)(( newInt32 >> 16 ) & 0xFF )
01563               << (char)(( newInt32 >> 24 ) & 0xFF );
01564          }
01565          tokens.clear();
01566       }
01567 
01568 #ifdef GDCM_NO_ANSI_STRING_STREAM
01569       s << std::ends; // to avoid oddities on Solaris
01570 #endif //GDCM_NO_ANSI_STRING_STREAM
01571       return s.str();
01572    }
01573 
01574    return ((ValEntry *)entry)->GetValue();
01575 }

std::string gdcm::Document::GetDocEntryValue DocEntry entry  )  [private]
 

Get the transformed value of the header entry. The VR value is used to define the transformation to operate on the value.

Warning:
NOT end user intended method !
Parameters:
entry entry to tranform
Returns:
Transformed entry value

Definition at line 1454 of file gdcmDocument.cxx.

References gdcm::DocEntry::GetLength(), gdcm::DocEntry::GetVR(), IsDocEntryAnInteger(), gdcm::DocEntry::IsImplicitVR(), SwapLong(), and SwapShort().

01455 {
01456    if ( IsDocEntryAnInteger(entry) && entry->IsImplicitVR() )
01457    {
01458       std::string val = ((ValEntry *)entry)->GetValue();
01459       std::string vr  = entry->GetVR();
01460       uint32_t length = entry->GetLength();
01461       std::ostringstream s;
01462       int nbInt;
01463 
01464       // When short integer(s) are expected, read and convert the following 
01465       // n * 2 bytes properly i.e. as a multivaluated strings
01466       // (each single value is separated fromthe next one by '\'
01467       // as usual for standard multivaluated filels
01468       // Elements with Value Multiplicity > 1
01469       // contain a set of short integers (not a single one) 
01470    
01471       if( vr == "US" || vr == "SS" )
01472       {
01473          uint16_t newInt16;
01474 
01475          nbInt = length / 2;
01476          for (int i=0; i < nbInt; i++) 
01477          {
01478             if( i != 0 )
01479             {
01480                s << '\\';
01481             }
01482             newInt16 = ( val[2*i+0] & 0xFF ) + ( ( val[2*i+1] & 0xFF ) << 8);
01483             newInt16 = SwapShort( newInt16 );
01484             s << newInt16;
01485          }
01486       }
01487 
01488       // When integer(s) are expected, read and convert the following 
01489       // n * 4 bytes properly i.e. as a multivaluated strings
01490       // (each single value is separated fromthe next one by '\'
01491       // as usual for standard multivaluated filels
01492       // Elements with Value Multiplicity > 1
01493       // contain a set of integers (not a single one) 
01494       else if( vr == "UL" || vr == "SL" )
01495       {
01496          uint32_t newInt32;
01497 
01498          nbInt = length / 4;
01499          for (int i=0; i < nbInt; i++) 
01500          {
01501             if( i != 0)
01502             {
01503                s << '\\';
01504             }
01505             newInt32 = ( val[4*i+0] & 0xFF )
01506                     + (( val[4*i+1] & 0xFF ) <<  8 )
01507                     + (( val[4*i+2] & 0xFF ) << 16 )
01508                     + (( val[4*i+3] & 0xFF ) << 24 );
01509             newInt32 = SwapLong( newInt32 );
01510             s << newInt32;
01511          }
01512       }
01513 #ifdef GDCM_NO_ANSI_STRING_STREAM
01514       s << std::ends; // to avoid oddities on Solaris
01515 #endif //GDCM_NO_ANSI_STRING_STREAM
01516       return s.str();
01517    }
01518    return ((ValEntry *)entry)->GetValue();
01519 }

void * gdcm::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 57 of file gdcmDocEntrySet.cxx.

References gdcm::BinEntry::GetBinArea(), and gdcm::DocEntrySet::GetBinEntry().

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

00058 {
00059    BinEntry *entry = GetBinEntry(group, elem);
00060    if( entry )
00061       return entry->GetBinArea();
00062    return 0;
00063 }

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

Searches within Header Entries (Dicom Elements) parsed with the public and private dictionaries 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; -2 if not found

Definition at line 73 of file gdcmDocEntrySet.cxx.

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

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

00074 {
00075    DocEntry *entry = GetDocEntry(group, elem);
00076    if( entry )
00077       return entry->GetLength();
00078    return -1;
00079 }

std::string gdcm::DocEntrySet::GetEntryValue 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 ("gdcm::Unfound") otherwise.

Definition at line 43 of file gdcmDocEntrySet.cxx.

References gdcm::GDCM_UNFOUND, gdcm::DocEntrySet::GetDocEntry(), and gdcm::ContentEntry::GetValue().

Referenced by gdcm::SerieHelper::AddFileName(), gdcm::File::AnonymizeFile(), Document(), gdcm::File::File(), gdcm::File::GetBitsAllocated(), gdcm::File::GetBitsStored(), gdcm::File::GetHighBitPosition(), gdcm::File::GetImageNumber(), gdcm::File::GetImageOrientationPatient(), gdcm::File::GetLUTNbits(), gdcm::File::GetModality(), gdcm::File::GetNumberOfScalarComponents(), gdcm::File::GetPixelType(), gdcm::File::GetPlanarConfiguration(), gdcm::File::GetRescaleIntercept(), gdcm::File::GetRescaleSlope(), gdcm::File::GetSamplesPerPixel(), GetTransferSyntaxName(), gdcm::File::GetXOrigin(), gdcm::File::GetXSize(), gdcm::File::GetXSpacing(), gdcm::File::GetYOrigin(), gdcm::File::GetYSize(), gdcm::File::GetYSpacing(), gdcm::File::GetZOrigin(), gdcm::File::GetZSize(), gdcm::File::GetZSpacing(), gdcm::PixelReadConvert::GrabInformationsFromFile(), gdcm::File::IsMonochrome(), gdcm::File::IsPaletteColor(), gdcm::File::IsReadable(), gdcm::File::IsSignedPixelData(), gdcm::File::IsYBRFull(), operator<(), gdcm::DicomDir::SetElement(), and gdcm::File::Write().

00044 {
00045    ContentEntry *entry = dynamic_cast<ContentEntry *>(GetDocEntry(group,elem));
00046    if( entry )
00047       return entry->GetValue();
00048    return GDCM_UNFOUND;
00049 }

std::string gdcm::DocEntrySet::GetEntryVR uint16_t  group,
uint16_t  elem
[virtual, inherited]
 

Searches within Header Entries (Dicom Elements) parsed with the public [and private dictionaries] for the element value representation of a given tag.. Obtaining the VR (Value Representation) might be needed by caller to convert the string typed content to caller's native type (think of C++ vs Python). The VR is actually of a higher level of semantics than just the native C++ type.

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

Definition at line 94 of file gdcmDocEntrySet.cxx.

References gdcm::GDCM_UNFOUND, gdcm::DocEntrySet::GetDocEntry(), and gdcm::DocEntry::GetVR().

00095 {
00096    DocEntry *entry = GetDocEntry(group, elem);
00097    if( entry )
00098       return entry->GetVR();
00099    return GDCM_UNFOUND;
00100 }

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

Accessor to Filename.

Definition at line 79 of file gdcmDocument.h.

Referenced by gdcm::SerieHelper::FileNameLessThan(), gdcm::DicomDir::ParseDirectory(), and gdcm::DicomDir::SetElement().

00079 { return Filename; }

FileType gdcm::Document::GetFileType  ) 
 

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

Returns:
the FileType code

Definition at line 276 of file gdcmDocument.cxx.

References Filetype, and gdcm::FileType.

00277 {
00278    return Filetype;
00279 }

DocEntry * gdcm::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::DocEntrySet.

Definition at line 142 of file gdcmElementSet.cxx.

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

Referenced by ComputeGroup0002Length(), gdcm::DicomDir::DicomDir(), and gdcm::DicomDir::NewMeta().

00143 {
00144    ItTagHT = TagHT.begin();
00145    if (ItTagHT != TagHT.end())
00146       return  ItTagHT->second;
00147    return NULL;
00148 }

DocEntry * gdcm::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::DocEntrySet.

Definition at line 156 of file gdcmElementSet.cxx.

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

Referenced by ComputeGroup0002Length().

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

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

Gets the print level for the Dicom Entries.

Definition at line 48 of file gdcmBase.h.

00048 { return PrintLevel; };

Dict * gdcm::Document::GetPubDict  ) 
 

Get the public dictionary used.

Definition at line 183 of file gdcmDocument.cxx.

References RefPubDict.

Referenced by gdcm::DicomDir::SetElement().

00184 {
00185    return RefPubDict;
00186 }

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

Same as Document::GetDocEntry except it only returns a result 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 148 of file gdcmDocEntrySet.cxx.

References gdcmWarningMacro, and gdcm::DocEntrySet::GetDocEntry().

00149 {
00150    DocEntry *currentEntry = GetDocEntry(group, elem);
00151    if ( !currentEntry )
00152    {
00153       gdcmWarningMacro( "No corresponding SeqEntry " << std::hex << group <<
00154                         "," << elem);
00155       return NULL;
00156    }
00157 
00158    return dynamic_cast<SeqEntry*>(currentEntry);
00159 }

Dict * gdcm::Document::GetShaDict  ) 
 

Get the shadow dictionary used.

Definition at line 191 of file gdcmDocument.cxx.

References RefShaDict.

00192 {
00193    return RefShaDict;
00194 }

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

'Swap code' accessor (see SwapCode )

Definition at line 66 of file gdcmDocument.h.

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

00066 { return SwapCode; }

std::string gdcm::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.

Definition at line 287 of file gdcmDocument.cxx.

References gdcm::GDCM_UNKNOWN, gdcm::ElementSet::GetDocEntry(), gdcm::ContentEntry::GetValue(), and LoadDocEntrySafe().

Referenced by gdcm::File::ComputeJPEGFragmentInfo(), gdcm::File::ComputeRLEInfo(), gdcm::File::File(), gdcm::PixelReadConvert::GrabInformationsFromFile(), and HandleOutOfGroup0002().

00288 {
00289    DocEntry *entry = GetDocEntry(0x0002, 0x0010);
00290    if ( !entry )
00291    {
00292       return GDCM_UNKNOWN;
00293    }
00294 
00295    // The entry might be present but not loaded (parsing and loading
00296    // happen at different stages): try loading and proceed with check...
00297    LoadDocEntrySafe(entry);
00298    if (ValEntry *valEntry = dynamic_cast< ValEntry* >(entry) )
00299    {
00300       std::string transfer = valEntry->GetValue();
00301       // The actual transfer (as read from disk) might be padded. We
00302       // first need to remove the potential padding. We can make the
00303       // weak assumption that padding was not executed with digits...
00304       if  ( transfer.length() == 0 )
00305       {
00306          // for brain damaged headers
00307          return GDCM_UNKNOWN;
00308       }
00309       while ( !isdigit((unsigned char)transfer[transfer.length()-1]) )
00310       {
00311          transfer.erase(transfer.length()-1, 1);
00312       }
00313       return transfer;
00314    }
00315    return GDCM_UNKNOWN;
00316 }

std::string gdcm::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 322 of file gdcmDocument.cxx.

References gdcm::GDCM_NOTLOADED, gdcm::GDCM_UNFOUND, gdcmErrorMacro, gdcmWarningMacro, and gdcm::DocEntrySet::GetEntryValue().

Referenced by HandleOutOfGroup0002().

00323 {
00324    // use the TS (TS : Transfer Syntax)
00325    std::string transferSyntax = GetEntryValue(0x0002,0x0010);
00326 
00327    if ( (transferSyntax.find(GDCM_NOTLOADED) < transferSyntax.length()) )
00328    {
00329       gdcmErrorMacro( "Transfer Syntax not loaded. " << std::endl
00330                << "Better you increase MAX_SIZE_LOAD_ELEMENT_VALUE" );
00331       return "Uncompressed ACR-NEMA";
00332    }
00333    if ( transferSyntax == GDCM_UNFOUND )
00334    {
00335       gdcmWarningMacro( "Unfound Transfer Syntax (0002,0010)");
00336       return "Uncompressed ACR-NEMA";
00337    }
00338 
00339    // we do it only when we need it
00340    const TSKey &tsName = Global::GetTS()->GetValue( transferSyntax );
00341 
00342    // Global::GetTS() is a global static you shall never try to delete it!
00343    return tsName;
00344 }

ValEntry * gdcm::DocEntrySet::GetValEntry uint16_t  group,
uint16_t  elem
[inherited]
 

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

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

Definition at line 110 of file gdcmDocEntrySet.cxx.

References gdcm::DocEntrySet::GetDocEntry().

Referenced by gdcm::DocEntrySet::SetValEntry(), and gdcm::File::Write().

00111 {
00112    DocEntry *currentEntry = GetDocEntry(group, elem);
00113    if ( !currentEntry )
00114       return NULL;
00115 
00116    return dynamic_cast<ValEntry*>(currentEntry);
00117 }

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

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

Returns:
no return

Definition at line 2052 of file gdcmDocument.cxx.

References SwitchByteSwapCode().

Referenced by ReadNextDocEntry().

02053 {
02054    // Endian reversion. Some files contain groups of tags with reversed endianess.
02055    static int reversedEndian = 0;
02056    // try to fix endian switching in the middle of headers
02057    if ((group == 0xfeff) && (elem == 0x00e0))
02058    {
02059      // start endian swap mark for group found
02060      reversedEndian++;
02061      SwitchByteSwapCode();
02062      // fix the tag
02063      group = 0xfffe;
02064      elem  = 0xe000;
02065    } 
02066    else if (group == 0xfffe && elem == 0xe00d && reversedEndian) 
02067    {
02068      // end of reversed endian group
02069      reversedEndian--;
02070      SwitchByteSwapCode();
02071    }
02072 }

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

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

Returns:
no return

Definition at line 2079 of file gdcmDocument.cxx.

References Filetype, gdcmWarningMacro, GetTransferSyntax(), GetTransferSyntaxName(), Group0002Parsed, gdcm::ImplicitVR, SwapShort(), and SwitchByteSwapCode().

Referenced by ReadNextDocEntry().

02080 {
02081    // Endian reversion. Some files contain groups of tags with reversed endianess.
02082    if ( !Group0002Parsed && group != 0x0002)
02083    {
02084       Group0002Parsed = true;
02085       // we just came out of group 0002
02086       // if Transfer syntax is Big Endian we have to change CheckSwap
02087 
02088       std::string ts = GetTransferSyntax();
02089       if ( !Global::GetTS()->IsTransferSyntax(ts) )
02090       {
02091          gdcmWarningMacro("True DICOM File, with NO Tansfer Syntax: " << ts );
02092          return;
02093       }
02094 
02095       // Group 0002 is always 'Explicit ...' enven when Transfer Syntax says 'Implicit ..." 
02096 
02097       if ( Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ImplicitVRLittleEndian )
02098          {
02099             Filetype = ImplicitVR;
02100          }
02101        
02102       // FIXME Strangely, this works with 
02103       //'Implicit VR Transfer Syntax (GE Private)
02104       if ( Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ExplicitVRBigEndian )
02105       {
02106          gdcmWarningMacro("Transfer Syntax Name = [" 
02107                         << GetTransferSyntaxName() << "]" );
02108          SwitchByteSwapCode();
02109          group = SwapShort(group);
02110          elem  = SwapShort(elem);
02111       }
02112    }
02113 }

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

Loads all the needed Dictionaries.

Warning:
NOT end user intended method !

Reimplemented in gdcm::DicomDir.

Definition at line 764 of file gdcmDocument.cxx.

References Filetype, RefPubDict, RefShaDict, and gdcm::Unknown.

Referenced by Document().

00765 {
00766    RefPubDict = Global::GetDicts()->GetDefaultPubDict();
00767    RefShaDict = NULL;
00768    Filetype   = Unknown;
00769 }

BinEntry * gdcm::DocEntrySet::InsertBinEntry uint8_t *  binArea,
int  lgth,
uint16_t  group,
uint16_t  elem,
TagName const &  vr = GDCM_UNKNOWN
[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 309 of file gdcmDocEntrySet.cxx.

References gdcm::DocEntrySet::AddEntry(), gdcmWarningMacro, gdcm::DocEntrySet::GetDocEntry(), gdcm::DocEntry::GetVR(), gdcm::DocEntrySet::NewBinEntry(), gdcm::DocEntrySet::RemoveEntry(), gdcm::DocEntrySet::SetBinEntry(), and gdcm::TagName.

Referenced by gdcm::File::InitializeDefaultFile(), and gdcm::FileHelper::InsertBinEntry().

00312 {
00313    BinEntry *binEntry = 0;
00314    DocEntry *currentEntry = GetDocEntry( group, elem );
00315 
00316    // Verify the currentEntry
00317    if (currentEntry)
00318    {
00319       binEntry = dynamic_cast<BinEntry *>(currentEntry);
00320 
00321       // Verify the VR
00322       if( binEntry )
00323          if( binEntry->GetVR()!=vr )
00324             binEntry = NULL;
00325 
00326       // if currentEntry doesn't correspond to the requested valEntry
00327       if( !binEntry)
00328       {
00329          if( !RemoveEntry(currentEntry) )
00330          {
00331             gdcmWarningMacro( "Removal of previous DocEntry failed.");
00332 
00333             return NULL;
00334          }
00335       }
00336    }
00337 
00338    // Create a new binEntry if necessary
00339    if( !binEntry)
00340    {
00341       binEntry = NewBinEntry(group, elem, vr);
00342 
00343       if ( !AddEntry(binEntry) )
00344       {
00345          gdcmWarningMacro( "AddEntry failed allthough this is a creation.");
00346 
00347          delete binEntry;
00348          return NULL;
00349       }
00350    }
00351 
00352    // Set the binEntry value
00353    uint8_t *tmpArea;
00354    if( lgth>0 && binArea )
00355    {
00356       tmpArea = new uint8_t[lgth];
00357       memcpy(tmpArea,binArea,lgth);
00358    }
00359    else
00360    {
00361       tmpArea = 0;
00362    }
00363    if( !SetBinEntry(tmpArea,lgth,binEntry) )
00364    {
00365       if( tmpArea )
00366       {
00367          delete[] tmpArea;
00368       }
00369    }
00370 
00371    return binEntry;
00372 }  

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

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

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

Definition at line 382 of file gdcmDocEntrySet.cxx.

References gdcm::DocEntrySet::AddEntry(), gdcmWarningMacro, gdcm::DocEntrySet::GetDocEntry(), gdcm::DocEntrySet::NewSeqEntry(), and gdcm::DocEntrySet::RemoveEntry().

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

00383 {
00384    SeqEntry *seqEntry = 0;
00385    DocEntry *currentEntry = GetDocEntry( group, elem );
00386 
00387    // Verify the currentEntry
00388    if( currentEntry )
00389    {
00390       seqEntry = dynamic_cast<SeqEntry *>(currentEntry);
00391 
00392       // Verify the VR
00393       if( seqEntry )
00394          seqEntry = NULL;
00395 
00396       // if currentEntry doesn't correspond to the requested seqEntry
00397       if( !seqEntry )
00398       {
00399          if (!RemoveEntry(currentEntry))
00400          {
00401             gdcmWarningMacro( "Removal of previous DocEntry failed.");
00402 
00403             return NULL;
00404          }
00405       }
00406    }
00407    // Create a new seqEntry if necessary
00408    if( !seqEntry )
00409    {
00410       seqEntry = NewSeqEntry(group, elem);
00411 
00412       if( !AddEntry(seqEntry) )
00413       {
00414          gdcmWarningMacro( "AddEntry failed allthough this is a creation.");
00415 
00416          delete seqEntry;
00417          return NULL;
00418       }
00419    }
00420 
00421    // TODO : Find a trick to insert a SequenceDelimitationItem 
00422         //       in the SeqEntry, at the end.
00423    return seqEntry;
00424 } 

ValEntry * gdcm::DocEntrySet::InsertValEntry std::string const &  value,
uint16_t  group,
uint16_t  elem,
TagName const &  vr = GDCM_UNKNOWN
[inherited]
 

Modifies the value of a given Doc Entry (Dicom Element) when it exists. Create 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 250 of file gdcmDocEntrySet.cxx.

References gdcm::DocEntrySet::AddEntry(), gdcmWarningMacro, gdcm::DocEntrySet::GetDocEntry(), gdcm::DocEntry::GetVR(), gdcm::DocEntrySet::NewValEntry(), gdcm::DocEntrySet::RemoveEntry(), gdcm::DocEntrySet::SetValEntry(), and gdcm::TagName.

Referenced by gdcm::File::InitializeDefaultFile(), gdcm::FileHelper::InsertValEntry(), and gdcm::File::Write().

00253 {
00254    ValEntry *valEntry = 0;
00255    DocEntry *currentEntry = GetDocEntry( group, elem );
00256    
00257    if (currentEntry)
00258    {
00259       valEntry = dynamic_cast<ValEntry *>(currentEntry);
00260 
00261       // Verify the VR
00262       if( valEntry )
00263          if( valEntry->GetVR()!=vr )
00264             valEntry = NULL;
00265 
00266       // if currentEntry doesn't correspond to the requested valEntry
00267       if( !valEntry)
00268       {
00269          if( !RemoveEntry(currentEntry) )
00270          {
00271             gdcmWarningMacro( "Removal of previous DocEntry failed.");
00272 
00273             return NULL;
00274          }
00275       }
00276    }
00277 
00278    // Create a new valEntry if necessary
00279    if( !valEntry )
00280    {
00281       valEntry = NewValEntry( group, elem, vr );
00282 
00283       if ( !AddEntry(valEntry) )
00284       {
00285          gdcmWarningMacro("AddEntry failed although this is a creation.");
00286 
00287          delete valEntry;
00288          return NULL;
00289       }
00290    }
00291 
00292    // Set the binEntry value
00293    SetValEntry(value, valEntry); // The std::string value
00294    return valEntry;
00295 }

bool gdcm::Document::IsDicomV3  ) 
 

Predicate for dicom version 3 file.

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

Definition at line 245 of file gdcmDocument.cxx.

References gdcm::ElementSet::GetDocEntry().

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

00246 {
00247    // Checking if Transfer Syntax exists is enough
00248    // Anyway, it's to late check if the 'Preamble' was found ...
00249    // And ... would it be a rich idea to check ?
00250    // (some 'no Preamble' DICOM images exist !)
00251    return GetDocEntry(0x0002, 0x0010) != NULL;
00252 }

bool gdcm::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 1677 of file gdcmDocument.cxx.

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

Referenced by GetDocEntryUnvalue(), GetDocEntryValue(), and LoadDocEntry().

01678 {
01679    uint16_t elem          = entry->GetElement();
01680    uint16_t group         = entry->GetGroup();
01681    const std::string &vr  = entry->GetVR();
01682    uint32_t length        = entry->GetLength();
01683 
01684    // When we have some semantics on the element we just read, and if we
01685    // a priori know we are dealing with an integer, then we shall be
01686    // able to swap it's element value properly.
01687    if ( elem == 0 )  // This is the group length of the group
01688    {  
01689       if ( length == 4 )
01690       {
01691          return true;
01692       }
01693       else 
01694       {
01695          // Allthough this should never happen, still some images have a
01696          // corrupted group length [e.g. have a glance at offset x(8336) of
01697          // gdcmData/gdcm-MR-PHILIPS-16-Multi-Seq.dcm].
01698          // Since for dicom compliant and well behaved headers, the present
01699          // test is useless (and might even look a bit paranoid), when we
01700          // encounter such an ill-formed image, we simply display a warning
01701          // message and proceed on parsing (while crossing fingers).
01702          long filePosition = Fp->tellg();
01703          gdcmWarningMacro( "Erroneous Group Length element length  on : (" 
01704            << std::hex << group << " , " << elem
01705            << ") -before- position x(" << filePosition << ")"
01706            << "lgt : " << length );
01707       }
01708    }
01709 
01710    if ( vr == "UL" || vr == "US" || vr == "SL" || vr == "SS" )
01711    {
01712       return true;
01713    }   
01714    return false;
01715 }

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

Tells us if the ElementSet contains no entry.

Implements gdcm::DocEntrySet.

Definition at line 63 of file gdcmElementSet.h.

Referenced by IsReadable().

00063 { return TagHT.empty(); };

bool gdcm::Document::IsPapyrus  ) 
 

Predicate for Papyrus file Dedicated to whomsoever it may concern.

Returns:
True when the file is a Papyrus file.

Definition at line 259 of file gdcmDocument.cxx.

References gdcm::ElementSet::GetDocEntry().

00260 {
00261    // check for Papyrus private Sequence
00262    DocEntry *e = GetDocEntry(0x0041, 0x1050);
00263    if ( !e )
00264       return false;
00265    // check if it's actually a Sequence
00266    if ( !dynamic_cast<SeqEntry*>(e) )
00267       return  false;
00268    return true;
00269 }

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

This predicate, based on hopefully reasonable heuristics, decides whether or not the current Document was properly parsed and contains the mandatory information for being considered as a well formed and usable Dicom/Acr File.

Returns:
true when Document is the one of a reasonable Dicom/Acr file, false otherwise.

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

Definition at line 224 of file gdcmDocument.cxx.

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

00225 {
00226    if( Filetype == Unknown)
00227    {
00228       gdcmWarningMacro( "Wrong filetype");
00229       return false;
00230    }
00231 
00232    if ( IsEmpty() )
00233    { 
00234       gdcmWarningMacro( "No tag in internal hash table.");
00235       return false;
00236    }
00237 
00238    return true;
00239 }

void gdcm::Document::LoadDocEntry DocEntry entry  )  [private]
 

Loads the element content if its length doesn't exceed the value specified with Document::SetMaxSizeLoadEntry().

Parameters:
entry Header Entry (Dicom Element) to be dealt with

Todo:
Any compacter code suggested (?)

Definition at line 1030 of file gdcmDocument.cxx.

References Fp, gdcm::GDCM_BINLOADED, gdcm::GDCM_NOTLOADED, gdcm::GDCM_UNREAD, gdcmErrorMacro, gdcmWarningMacro, gdcm::DocEntry::GetGroup(), gdcm::DocEntry::GetLength(), gdcm::DocEntry::GetOffset(), gdcm::DocEntry::GetVR(), IsDocEntryAnInteger(), LoadEntryBinArea(), MaxSizeLoadEntry, ReadInt16(), ReadInt32(), gdcm::ValEntry::SetValue(), and gdcm::ContentEntry::SetValue().

Referenced by LoadDocEntrySafe(), and ParseDES().

01031 {
01032    uint16_t group  = entry->GetGroup();
01033    std::string  vr = entry->GetVR();
01034    uint32_t length = entry->GetLength();
01035 
01036    Fp->seekg((long)entry->GetOffset(), std::ios::beg);
01037 
01038    // A SeQuence "contains" a set of Elements.  
01039    //          (fffe e000) tells us an Element is beginning
01040    //          (fffe e00d) tells us an Element just ended
01041    //          (fffe e0dd) tells us the current SeQuence just ended
01042    if( group == 0xfffe )
01043    {
01044       // NO more value field for SQ !
01045       return;
01046    }
01047 
01048    // When the length is zero things are easy:
01049    if ( length == 0 )
01050    {
01051       ((ValEntry *)entry)->SetValue("");
01052       return;
01053    }
01054 
01055    // The elements whose length is bigger than the specified upper bound
01056    // are not loaded. Instead we leave a short notice of the offset of
01057    // the element content and it's length.
01058 
01059    std::ostringstream s;
01060    if (length > MaxSizeLoadEntry)
01061    {
01062       if (BinEntry *binEntryPtr = dynamic_cast< BinEntry* >(entry) )
01063       {  
01064          //s << "gdcm::NotLoaded (BinEntry)";
01065          s << GDCM_NOTLOADED;
01066          s << " Address:" << (long)entry->GetOffset();
01067          s << " Length:"  << entry->GetLength();
01068          s << " x(" << std::hex << entry->GetLength() << ")";
01069          binEntryPtr->SetValue(s.str());
01070       }
01071       // Be carefull : a BinEntry IS_A ValEntry ... 
01072       else if (ValEntry *valEntryPtr = dynamic_cast< ValEntry* >(entry) )
01073       {
01074         // s << "gdcm::NotLoaded. (ValEntry)";
01075          s << GDCM_NOTLOADED;  
01076          s << " Address:" << (long)entry->GetOffset();
01077          s << " Length:"  << entry->GetLength();
01078          s << " x(" << std::hex << entry->GetLength() << ")";
01079          valEntryPtr->SetValue(s.str());
01080       }
01081       else
01082       {
01083          // fusible
01084          gdcmErrorMacro( "MaxSizeLoadEntry exceeded, neither a BinEntry "
01085                       << "nor a ValEntry ?! Should never print that !" );
01086       }
01087 
01088       // to be sure we are at the end of the value ...
01089       Fp->seekg((long)entry->GetOffset()+(long)entry->GetLength(),
01090                 std::ios::beg);
01091       return;
01092    }
01093 
01094    // When we find a BinEntry not very much can be done :
01095    if (BinEntry *binEntryPtr = dynamic_cast< BinEntry* >(entry) )
01096    {
01097       s << GDCM_BINLOADED;
01098       binEntryPtr->SetValue(s.str());
01099       LoadEntryBinArea(binEntryPtr); // last one, not to erase length !
01100       return;
01101    }
01102 
01104    if ( IsDocEntryAnInteger(entry) )
01105    {   
01106       uint32_t NewInt;
01107       int nbInt;
01108       // When short integer(s) are expected, read and convert the following 
01109       // n *two characters properly i.e. consider them as short integers as
01110       // opposed to strings.
01111       // Elements with Value Multiplicity > 1
01112       // contain a set of integers (not a single one)       
01113       if (vr == "US" || vr == "SS")
01114       {
01115          nbInt = length / 2;
01116          NewInt = ReadInt16();
01117          s << NewInt;
01118          if (nbInt > 1)
01119          {
01120             for (int i=1; i < nbInt; i++)
01121             {
01122                s << '\\';
01123                NewInt = ReadInt16();
01124                s << NewInt;
01125             }
01126          }
01127       }
01128       // See above comment on multiple integers (mutatis mutandis).
01129       else if (vr == "UL" || vr == "SL")
01130       {
01131          nbInt = length / 4;
01132          NewInt = ReadInt32();
01133          s << NewInt;
01134          if (nbInt > 1)
01135          {
01136             for (int i=1; i < nbInt; i++)
01137             {
01138                s << '\\';
01139                NewInt = ReadInt32();
01140                s << NewInt;
01141             }
01142          }
01143       }
01144 #ifdef GDCM_NO_ANSI_STRING_STREAM
01145       s << std::ends; // to avoid oddities on Solaris
01146 #endif //GDCM_NO_ANSI_STRING_STREAM
01147 
01148       ((ValEntry *)entry)->SetValue(s.str());
01149       return;
01150    }
01151    
01152   // FIXME: We need an additional byte for storing \0 that is not on disk
01153    char *str = new char[length+1];
01154    Fp->read(str, (size_t)length);
01155    str[length] = '\0'; //this is only useful when length is odd
01156    // Special DicomString call to properly handle \0 and even length
01157    std::string newValue;
01158    if( length % 2 )
01159    {
01160       newValue = Util::DicomString(str, length+1);
01161       gdcmWarningMacro("Warning: bad length: " << length <<
01162                        ",For string :" <<  newValue.c_str()); 
01163       // Since we change the length of string update it length
01164       //entry->SetReadLength(length+1);
01165    }
01166    else
01167    {
01168       newValue = Util::DicomString(str, length);
01169    }
01170    delete[] str;
01171 
01172    if ( ValEntry *valEntry = dynamic_cast<ValEntry* >(entry) )
01173    {
01174       if ( Fp->fail() || Fp->eof())
01175       {
01176          gdcmWarningMacro("Unread element value");
01177          valEntry->SetValue(GDCM_UNREAD);
01178          return;
01179       }
01180 
01181       if( vr == "UI" )
01182       {
01183          // Because of correspondance with the VR dic
01184          valEntry->SetValue(newValue);
01185       }
01186       else
01187       {
01188          valEntry->SetValue(newValue);
01189       }
01190    }
01191    else
01192    {
01193       gdcmErrorMacro( "Should have a ValEntry, here !");
01194    }
01195 }

void gdcm::Document::LoadDocEntrySafe DocEntry entry  ) 
 

Loads the element while preserving the current underlying file position indicator as opposed to LoadDocEntry that modifies it.

Parameters:
entry DocEntry whose value will be loaded.

Definition at line 581 of file gdcmDocument.cxx.

References Fp, and LoadDocEntry().

Referenced by GetTransferSyntax().

00582 {
00583    if(Fp)
00584    {
00585       long PositionOnEntry = Fp->tellg();
00586       LoadDocEntry(entry);
00587       Fp->seekg(PositionOnEntry, std::ios::beg);
00588    }
00589 }

void gdcm::Document::LoadEntryBinArea BinEntry elem  )  [virtual]
 

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

Parameters:
elem Entry whose binArea is going to be loaded

Todo:
check the result

Definition at line 541 of file gdcmDocument.cxx.

References CloseFile(), Fp, gdcmWarningMacro, gdcm::BinEntry::GetBinArea(), gdcm::DocEntry::GetLength(), gdcm::DocEntry::GetOffset(), OpenFile(), and gdcm::BinEntry::SetBinArea().

00542 {
00543    if(elem->GetBinArea())
00544       return;
00545 
00546    bool openFile = !Fp;
00547    if(openFile)
00548       OpenFile();
00549 
00550    size_t o =(size_t)elem->GetOffset();
00551    Fp->seekg(o, std::ios::beg);
00552 
00553    size_t l = elem->GetLength();
00554    uint8_t *a = new uint8_t[l];
00555    if( !a )
00556    {
00557       gdcmWarningMacro( "Cannot allocate BinEntry content");
00558       return;
00559    }
00560 
00562    Fp->read((char*)a, l);
00563    if( Fp->fail() || Fp->eof())
00564    {
00565       delete[] a;
00566       return;
00567    }
00568 
00569    elem->SetBinArea(a);
00570 
00571    if(openFile)
00572       CloseFile();
00573 }

void gdcm::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 522 of file gdcmDocument.cxx.

References gdcm::ElementSet::GetDocEntry().

Referenced by Document(), gdcm::PixelReadConvert::GrabInformationsFromFile(), and LoadDocEntry().

00523 {
00524    // Search the corresponding DocEntry
00525    DocEntry *docElement = GetDocEntry(group, elem);
00526    if ( !docElement )
00527       return;
00528 
00529    BinEntry *binElement = dynamic_cast<BinEntry *>(docElement);
00530    if( !binElement )
00531       return;
00532 
00533    LoadEntryBinArea(binElement);
00534 }

BinEntry * gdcm::DocEntrySet::NewBinEntry uint16_t  group,
uint16_t  elem,
TagName const &  vr = GDCM_UNKNOWN
[inherited]
 

Build a new Bin Entry from all the low level arguments. Check for existence of dictionary entry, and build a default one when absent.

Parameters:
group group number of the new Entry
elem element number of the new Entry
vr VR of the new Entry

Definition at line 471 of file gdcmDocEntrySet.cxx.

References gdcmAssertMacro, gdcmWarningMacro, gdcm::DocEntrySet::GetDictEntry(), and gdcm::TagName.

Referenced by gdcm::FileHelper::CopyBinEntry(), gdcm::DocEntrySet::InsertBinEntry(), and ReadNextDocEntry().

00473 {
00474    DictEntry *dictEntry = GetDictEntry(group, elem, vr);
00475    gdcmAssertMacro(dictEntry);
00476 
00477    BinEntry *newEntry = new BinEntry(dictEntry);
00478    if (!newEntry) 
00479    {
00480       gdcmWarningMacro( "Failed to allocate BinEntry");
00481       return 0;
00482    }
00483    return newEntry;
00484 }

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

Build a new Seq Entry from all the low level arguments. Check for existence of dictionary entry, and build a default one when absent.

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

Definition at line 493 of file gdcmDocEntrySet.cxx.

References gdcmAssertMacro, gdcmWarningMacro, and gdcm::DocEntrySet::GetDictEntry().

Referenced by gdcm::DocEntrySet::InsertSeqEntry(), and ReadNextDocEntry().

00494 {
00495    DictEntry *dictEntry = GetDictEntry(group, elem, "SQ");
00496    gdcmAssertMacro(dictEntry);
00497 
00498    SeqEntry *newEntry = new SeqEntry( dictEntry );
00499    if (!newEntry)
00500    {
00501       gdcmWarningMacro( "Failed to allocate SeqEntry");
00502       return 0;
00503    }
00504    return newEntry;
00505 }

ValEntry * gdcm::DocEntrySet::NewValEntry uint16_t  group,
uint16_t  elem,
TagName const &  vr = GDCM_UNKNOWN
[inherited]
 

Build a new Val Entry from all the low level arguments. Check for existence of dictionary entry, and build a default one when absent.

Parameters:
group group number of the new Entry
elem element number of the new Entry
vr VR of the new Entry

Definition at line 447 of file gdcmDocEntrySet.cxx.

References gdcmAssertMacro, gdcmWarningMacro, gdcm::DocEntrySet::GetDictEntry(), and gdcm::TagName.

Referenced by gdcm::FileHelper::CopyValEntry(), gdcm::DocEntrySet::InsertValEntry(), and ReadNextDocEntry().

00449 {
00450    DictEntry *dictEntry = GetDictEntry(group, elem, vr);
00451    gdcmAssertMacro(dictEntry);
00452 
00453    ValEntry *newEntry = new ValEntry(dictEntry);
00454    if (!newEntry) 
00455    {
00456       gdcmWarningMacro( "Failed to allocate ValEntry");
00457       return 0;
00458    }
00459    return newEntry;
00460 }

DictEntry * gdcm::DocEntrySet::NewVirtualDictEntry uint16_t  group,
uint16_t  elem,
TagName const &  vr = GDCM_UNKNOWN,
TagName const &  vm = GDCM_UNKNOWN,
TagName const &  name = GDCM_UNKNOWN
[inherited]
 

Request a new virtual dict entry to the dict set.

Parameters:
group group number of the underlying DictEntry
elem element number of the underlying DictEntry
vr VR (Value Representation) of the underlying DictEntry
vm VM (Value Multiplicity) of the underlying DictEntry
name english name

Definition at line 515 of file gdcmDocEntrySet.cxx.

References gdcm::TagName.

Referenced by gdcm::File::File(), and gdcm::DocEntrySet::GetDictEntry().

00519 {
00520    return Global::GetDicts()->NewVirtualDictEntry(group,elem,vr,vm,name);
00521 }

std::ifstream * gdcm::Document::OpenFile  ) 
 

Tries to open the file Document::Filename and checks the preamble when existing.

Returns:
The FILE pointer on success.

Definition at line 395 of file gdcmDocument.cxx.

References CloseFile(), Fp, gdcmDebugMacro, gdcmWarningMacro, and HasDCMPreamble.

Referenced by Document(), gdcm::File::File(), gdcm::FileHelper::GetRaw(), and LoadEntryBinArea().

00396 {
00397    HasDCMPreamble = false;
00398    if (Filename.length() == 0) 
00399    {
00400       return 0;
00401    }
00402 
00403    if(Fp)
00404    {
00405       gdcmWarningMacro( "File already open: " << Filename.c_str());
00406       CloseFile();
00407    }
00408 
00409    Fp = new std::ifstream(Filename.c_str(), std::ios::in | std::ios::binary);
00410    if( ! *Fp )
00411    {
00412       gdcmDebugMacro( "Cannot open file: " << Filename.c_str());
00413       delete Fp;
00414       Fp = 0;
00415       return 0;
00416    }
00417  
00418    uint16_t zero = 0;
00419    Fp->read((char*)&zero, (size_t)2);
00420    if( Fp->eof() )
00421    {
00422       CloseFile();
00423       return 0;
00424    }
00425  
00426    //ACR -- or DICOM with no Preamble; may start with a Shadow Group --
00427    if( 
00428        zero == 0x0001 || zero == 0x0100 || zero == 0x0002 || zero == 0x0200 ||
00429        zero == 0x0003 || zero == 0x0300 || zero == 0x0004 || zero == 0x0400 ||
00430        zero == 0x0005 || zero == 0x0500 || zero == 0x0006 || zero == 0x0600 ||
00431        zero == 0x0007 || zero == 0x0700 || zero == 0x0008 || zero == 0x0800 )
00432    {
00433       std::string msg 
00434          = Util::Format("ACR/DICOM with no preamble: (%04x)\n", zero);
00435       gdcmWarningMacro( msg.c_str() );
00436       return Fp;
00437    }
00438  
00439    //DICOM
00440    Fp->seekg(126L, std::ios::cur);
00441    char dicm[4] = {' ',' ',' ',' '};
00442    Fp->read(dicm,  (size_t)4);
00443    if( Fp->eof() )
00444    {
00445       CloseFile();
00446       return 0;
00447    }
00448    if( memcmp(dicm, "DICM", 4) == 0 )
00449    {
00450       HasDCMPreamble = true;
00451       return Fp;
00452    }
00453  
00454    CloseFile();
00455    gdcmWarningMacro( "Not DICOM/ACR (missing preamble)" << Filename.c_str());
00456  
00457    return 0;
00458 }

bool gdcm::Document::operator< Document document  ) 
 

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 598 of file gdcmDocument.cxx.

References gdcm::DocEntrySet::GetEntryValue().

00599 {
00600    // Patient Name
00601    std::string s1 = GetEntryValue(0x0010,0x0010);
00602    std::string s2 = document.GetEntryValue(0x0010,0x0010);
00603    if(s1 < s2)
00604    {
00605       return true;
00606    }
00607    else if( s1 > s2 )
00608    {
00609       return false;
00610    }
00611    else
00612    {
00613       // Patient ID
00614       s1 = GetEntryValue(0x0010,0x0020);
00615       s2 = document.GetEntryValue(0x0010,0x0020);
00616       if ( s1 < s2 )
00617       {
00618          return true;
00619       }
00620       else if ( s1 > s2 )
00621       {
00622          return false;
00623       }
00624       else
00625       {
00626          // Study Instance UID
00627          s1 = GetEntryValue(0x0020,0x000d);
00628          s2 = document.GetEntryValue(0x0020,0x000d);
00629          if ( s1 < s2 )
00630          {
00631             return true;
00632          }
00633          else if( s1 > s2 )
00634          {
00635             return false;
00636          }
00637          else
00638          {
00639             // Serie Instance UID
00640             s1 = GetEntryValue(0x0020,0x000e);
00641             s2 = document.GetEntryValue(0x0020,0x000e);    
00642             if ( s1 < s2 )
00643             {
00644                return true;
00645             }
00646             else if( s1 > s2 )
00647             {
00648                return false;
00649             }
00650          }
00651       }
00652    }
00653    return false;
00654 }

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

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

Returns:
length of the parsed set.

Definition at line 775 of file gdcmDocument.cxx.

References gdcm::DocEntrySet::AddEntry(), gdcm::ExplicitVR, Filetype, Fp, gdcmWarningMacro, gdcm::SQItem::GetBaseTagKey(), gdcm::SQItem::GetDepthLevel(), gdcm::DocEntry::GetElement(), gdcm::DocEntry::GetGroup(), gdcm::DocEntry::GetKey(), gdcm::DocEntry::GetOffset(), gdcm::DocEntry::GetReadLength(), gdcm::DocEntry::GetVR(), gdcm::DocEntry::IsItemDelimitor(), LoadDocEntry(), ParseSQ(), ReadNextDocEntry(), gdcm::SeqEntry::SetDelimitorMode(), gdcm::SeqEntry::SetDepthLevel(), gdcm::DocEntry::SetKey(), SkipToNextDocEntry(), and gdcm::VRKey.

Referenced by Document(), and ParseSQ().

00777 {
00778    DocEntry *newDocEntry = 0;
00779    ValEntry *newValEntry;
00780    BinEntry *newBinEntry;
00781    SeqEntry *newSeqEntry;
00782    VRKey vr;
00783    bool used = false;
00784 
00785    while (true)
00786    {
00787       if ( !delim_mode && ((long)(Fp->tellg())-offset) >= l_max)
00788       {
00789          break;
00790       }
00791 
00792       used = true;
00793       newDocEntry = ReadNextDocEntry( );
00794 
00795       if ( !newDocEntry )
00796       {
00797          break;
00798       }
00799 
00800       vr = newDocEntry->GetVR();
00801       newValEntry = dynamic_cast<ValEntry*>(newDocEntry);
00802       newBinEntry = dynamic_cast<BinEntry*>(newDocEntry);
00803       newSeqEntry = dynamic_cast<SeqEntry*>(newDocEntry);
00804 
00805       if ( newValEntry || newBinEntry )
00806       {
00807          if ( newBinEntry )
00808          {
00809             if ( Filetype == ExplicitVR && 
00810                  !Global::GetVR()->IsVROfBinaryRepresentable(vr) )
00811             { 
00813                 gdcmWarningMacro( std::hex << newDocEntry->GetGroup() 
00814                                   << "|" << newDocEntry->GetElement()
00815                                   << " : Neither Valentry, nor BinEntry." 
00816                                   "Probably unknown VR.");
00817             }
00818 
00820             // When "this" is a Document the Key is simply of the
00821             // form ( group, elem )...
00822             if ( dynamic_cast< Document* > ( set ) )
00823             {
00824                newBinEntry->SetKey( newBinEntry->GetKey() );
00825             }
00826             // but when "this" is a SQItem, we are inserting this new
00827             // valEntry in a sequence item, and the key has the
00828             // generalized form (refer to \ref BaseTagKey):
00829             if (SQItem *parentSQItem = dynamic_cast< SQItem* > ( set ) )
00830             {
00831                newBinEntry->SetKey(  parentSQItem->GetBaseTagKey()
00832                                    + newBinEntry->GetKey() );
00833             }
00834 
00835             LoadDocEntry( newBinEntry );
00836             if( !set->AddEntry( newBinEntry ) )
00837             {
00838               //Expect big troubles if here
00839               //delete newBinEntry;
00840               used=false;
00841             }
00842          }
00843          else
00844          {
00846             // When "set" is a Document, then we are at the top of the
00847             // hierarchy and the Key is simply of the form ( group, elem )...
00848             if ( dynamic_cast< Document* > ( set ) )
00849             {
00850                newValEntry->SetKey( newValEntry->GetKey() );
00851             }
00852             // ...but when "set" is a SQItem, we are inserting this new
00853             // valEntry in a sequence item. Hence the key has the
00854             // generalized form (refer to \ref BaseTagKey):
00855             if (SQItem *parentSQItem = dynamic_cast< SQItem* > ( set ) )
00856             {
00857                newValEntry->SetKey(  parentSQItem->GetBaseTagKey()
00858                                    + newValEntry->GetKey() );
00859             }
00860              
00861             LoadDocEntry( newValEntry );
00862             bool delimitor=newValEntry->IsItemDelimitor();
00863             if( !set->AddEntry( newValEntry ) )
00864             {
00865               // If here expect big troubles
00866               //delete newValEntry; //otherwise mem leak
00867               used=false;
00868             }
00869 
00870             if (delimitor)
00871             {
00872                if(!used)
00873                   delete newDocEntry;
00874                break;
00875             }
00876             if ( !delim_mode && ((long)(Fp->tellg())-offset) >= l_max)
00877             {
00878                if(!used)
00879                   delete newDocEntry;
00880                break;
00881             }
00882          }
00883 
00884          // Just to make sure we are at the beginning of next entry.
00885          SkipToNextDocEntry(newDocEntry);
00886       }
00887       else
00888       {
00889          // VR = "SQ"
00890          unsigned long l = newDocEntry->GetReadLength();            
00891          if ( l != 0 ) // don't mess the delim_mode for zero-length sequence
00892          {
00893             if ( l == 0xffffffff )
00894             {
00895               delim_mode = true;
00896             }
00897             else
00898             {
00899               delim_mode = false;
00900             }
00901          }
00902          // no other way to create it ...
00903          newSeqEntry->SetDelimitorMode( delim_mode );
00904 
00905          // At the top of the hierarchy, stands a Document. When "set"
00906          // is a Document, then we are building the first depth level.
00907          // Hence the SeqEntry we are building simply has a depth
00908          // level of one:
00909          if (/*Document *dummy =*/ dynamic_cast< Document* > ( set ) )
00910          {
00911             //(void)dummy;
00912             newSeqEntry->SetDepthLevel( 1 );
00913             newSeqEntry->SetKey( newSeqEntry->GetKey() );
00914          }
00915          // But when "set" is already a SQItem, we are building a nested
00916          // sequence, and hence the depth level of the new SeqEntry
00917          // we are building, is one level deeper:
00918          if (SQItem *parentSQItem = dynamic_cast< SQItem* > ( set ) )
00919          {
00920             newSeqEntry->SetDepthLevel( parentSQItem->GetDepthLevel() + 1 );
00921             newSeqEntry->SetKey(  parentSQItem->GetBaseTagKey()
00922                                 + newSeqEntry->GetKey() );
00923          }
00924 
00925          if ( l != 0 )
00926          {  // Don't try to parse zero-length sequences
00927             ParseSQ( newSeqEntry, 
00928                      newDocEntry->GetOffset(),
00929                      l, delim_mode);
00930          }
00931          if( !set->AddEntry( newSeqEntry ) )
00932          {
00933             used = false;
00934          }
00935          if ( !delim_mode && ((long)(Fp->tellg())-offset) >= l_max)
00936          {
00937             if( !used )
00938                delete newDocEntry;
00939             break;
00940          }
00941       }
00942 
00943       if( !used )
00944          delete newDocEntry;
00945    }
00946 }

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

Parses a Sequence ( SeqEntry after SeqEntry).

Returns:
parsed length for this level

Definition at line 952 of file gdcmDocument.cxx.

References gdcm::SeqEntry::AddSQItem(), Fp, gdcm::SeqEntry::GetDepthLevel(), gdcm::DocEntry::GetKey(), gdcm::DocEntry::GetReadLength(), gdcm::DocEntry::IsSequenceDelimitor(), ParseDES(), ReadNextDocEntry(), gdcm::SQItem::SetBaseTagKey(), and gdcm::SeqEntry::SetDelimitationItem().

Referenced by ParseDES().

00954 {
00955    int SQItemNumber = 0;
00956    bool dlm_mod;
00957    long offsetStartCurrentSQItem = offset;
00958 
00959    while (true)
00960    {
00961       // the first time, we read the fff0,e000 of the first SQItem
00962       DocEntry *newDocEntry = ReadNextDocEntry();
00963 
00964       if ( !newDocEntry )
00965       {
00966          // FIXME Should warn user
00967          break;
00968       }
00969       if( delim_mode )
00970       {
00971          if ( newDocEntry->IsSequenceDelimitor() )
00972          {
00973             seqEntry->SetDelimitationItem( newDocEntry ); 
00974             break;
00975          }
00976       }
00977       if ( !delim_mode && ((long)(Fp->tellg())-offset) >= l_max)
00978       {
00979          delete newDocEntry;
00980          break;
00981       }
00982       // create the current SQItem
00983       SQItem *itemSQ = new SQItem( seqEntry->GetDepthLevel() );
00984       std::ostringstream newBase;
00985       newBase << seqEntry->GetKey()
00986               << "/"
00987               << SQItemNumber
00988               << "#";
00989       itemSQ->SetBaseTagKey( newBase.str() );
00990       unsigned int l = newDocEntry->GetReadLength();
00991       
00992       if ( l == 0xffffffff )
00993       {
00994          dlm_mod = true;
00995       }
00996       else
00997       {
00998          dlm_mod = false;
00999       }
01000       // FIXME, TODO
01001       // when we're here, element fffe,e000 is already passed.
01002       // it's lost for the SQItem we're going to process !!
01003 
01004       //ParseDES(itemSQ, newDocEntry->GetOffset(), l, dlm_mod);
01005       //delete newDocEntry; // FIXME well ... it's too late to use it !
01006 
01007       // Let's try :------------
01008       // remove fff0,e000, created out of the SQItem
01009       delete newDocEntry;
01010       Fp->seekg(offsetStartCurrentSQItem, std::ios::beg);
01011       // fill up the current SQItem, starting at the beginning of fff0,e000
01012       ParseDES(itemSQ, offsetStartCurrentSQItem, l+8, dlm_mod);
01013       offsetStartCurrentSQItem = Fp->tellg();
01014       // end try -----------------
01015  
01016       seqEntry->AddSQItem( itemSQ, SQItemNumber ); 
01017       SQItemNumber++;
01018       if ( !delim_mode && ((long)(Fp->tellg())-offset ) >= l_max )
01019       {
01020          break;
01021       }
01022    }
01023 }

void gdcm::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::Base.

Reimplemented in gdcm::DicomDir.

Definition at line 195 of file gdcmElementSet.cxx.

References gdcm::DocEntry::Print(), gdcm::Base::SetPrintLevel(), and gdcm::ElementSet::TagHT.

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

00196 {
00197    for( TagDocEntryHT::const_iterator i = TagHT.begin(); i != TagHT.end(); ++i)
00198    {
00199       DocEntry *entry = i->second;
00200 
00201       entry->SetPrintLevel(PrintLevel);
00202       entry->Print(os);   
00203 
00204       if ( dynamic_cast<SeqEntry*>(entry) )
00205       {
00206          // Avoid the newline for a sequence:
00207          continue;
00208       }
00209       os << std::endl;
00210    }
00211 }

uint16_t gdcm::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 663 of file gdcmDocument.cxx.

Referenced by LoadDocEntry(), ReadNextDocEntry(), and gdcm::File::ReadTag().

00665 {
00666    uint16_t g;
00667    Fp->read ((char*)&g, (size_t)2);
00668    if ( Fp->fail() )
00669    {
00670       throw FormatError( "Document::ReadInt16()", " file error." );
00671    }
00672    if( Fp->eof() )
00673    {
00674       throw FormatError( "Document::ReadInt16()", "EOF." );
00675    }
00676    g = SwapShort(g); 
00677    return g;
00678 }

uint32_t gdcm::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 685 of file gdcmDocument.cxx.

Referenced by gdcm::File::ComputeRLEInfo(), LoadDocEntry(), and gdcm::File::ReadTagLength().

00687 {
00688    uint32_t g;
00689    Fp->read ((char*)&g, (size_t)4);
00690    if ( Fp->fail() )
00691    {
00692       throw FormatError( "Document::ReadInt32()", " file error." );
00693    }
00694    if( Fp->eof() )
00695    {
00696       throw FormatError( "Document::ReadInt32()", "EOF." );
00697    }
00698    g = SwapLong(g);
00699    return g;
00700 }

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

Read the next tag but WITHOUT loading it's value (read the 'Group Number', the 'Element Number', gets the Dict Entry gets the VR, gets the length, gets the offset value).

Returns:
On succes the newly created DocEntry, NULL on failure.

Definition at line 1970 of file gdcmDocument.cxx.

References gdcm::ExplicitVR, Filetype, FindDocEntryLength(), FindDocEntryVR(), Fp, gdcm::GDCM_UNKNOWN, gdcmWarningMacro, gdcm::DocEntrySet::GetDictEntry(), gdcm::DocEntry::GetElement(), gdcm::DocEntry::GetGroup(), gdcm::DictEntry::GetVR(), HandleBrokenEndian(), HandleOutOfGroup0002(), HasDCMPreamble, gdcm::DocEntrySet::NewBinEntry(), gdcm::DocEntrySet::NewSeqEntry(), gdcm::DocEntrySet::NewValEntry(), ReadInt16(), gdcm::DocEntry::SetImplicitVR(), and gdcm::DocEntry::SetOffset().

Referenced by ParseDES(), and ParseSQ().

01971 {
01972    uint16_t group;
01973    uint16_t elem;
01974 
01975    try
01976    {
01977       group = ReadInt16();
01978       elem  = ReadInt16();
01979    }
01980    catch ( FormatError e )
01981    {
01982       // We reached the EOF (or an error occured) therefore 
01983       // header parsing has to be considered as finished.
01984       return 0;
01985    }
01986 
01987    // Sometimes file contains groups of tags with reversed endianess.
01988    HandleBrokenEndian(group, elem);
01989 
01990    // In 'true DICOM' files Group 0002 is always little endian
01991    if ( HasDCMPreamble )
01992       HandleOutOfGroup0002(group, elem);
01993  
01994    std::string vr = FindDocEntryVR();
01995    std::string realVR = vr;
01996 
01997    if( vr == GDCM_UNKNOWN)
01998    {
01999       DictEntry *dictEntry = GetDictEntry(group,elem);
02000       if( dictEntry )
02001          realVR = dictEntry->GetVR();
02002    }
02003 
02004    DocEntry *newEntry;
02005    if( Global::GetVR()->IsVROfSequence(realVR) )
02006       newEntry = NewSeqEntry(group, elem);
02007    else if( Global::GetVR()->IsVROfStringRepresentable(realVR) )
02008       newEntry = NewValEntry(group, elem,vr);
02009    else
02010       newEntry = NewBinEntry(group, elem,vr);
02011 
02012    if( vr == GDCM_UNKNOWN )
02013    {
02014       if( Filetype == ExplicitVR )
02015       {
02016          // We thought this was explicit VR, but we end up with an
02017          // implicit VR tag. Let's backtrack.
02018          if ( newEntry->GetGroup() != 0xfffe )
02019          { 
02020             std::string msg;
02021             msg = Util::Format("Entry (%04x,%04x) should be Explicit VR\n", 
02022                           newEntry->GetGroup(), newEntry->GetElement());
02023             gdcmWarningMacro( msg.c_str() );
02024           }
02025       }
02026       newEntry->SetImplicitVR();
02027    }
02028 
02029    try
02030    {
02031       FindDocEntryLength(newEntry);
02032    }
02033    catch ( FormatError e )
02034    {
02035       // Call it quits
02036       //std::cout << e;
02037       delete newEntry;
02038       return 0;
02039    }
02040 
02041    newEntry->SetOffset(Fp->tellg());  
02042 
02043    return newEntry;
02044 }

bool gdcm::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::DocEntrySet.

Definition at line 89 of file gdcmElementSet.cxx.

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

Referenced by gdcm::File::File(), and gdcm::DocEntryArchive::Restore().

00090 {
00091    const TagKey &key = entryToRemove->GetKey();
00092    if( TagHT.count(key) == 1 )
00093    {
00094       TagHT.erase(key);
00095       //gdcmWarningMacro( "One element erased.");
00096       delete entryToRemove;
00097       return true;
00098    }
00099 
00100    gdcmWarningMacro( "Key not present");
00101    return false ;
00102 }

bool gdcm::ElementSet::RemoveEntryNoDestroy DocEntry entryToRemove  )  [virtual, inherited]
 

Clear the hash table from given entry BUT keep the entry.

Parameters:
entryToRemove Entry to remove.

Implements gdcm::DocEntrySet.

Definition at line 108 of file gdcmElementSet.cxx.

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

Referenced by gdcm::DicomDir::NewMeta(), gdcm::DocEntryArchive::Push(), and gdcm::File::Write().

00109 {
00110    const TagKey &key = entryToRemove->GetKey();
00111    if( TagHT.count(key) == 1 )
00112    {
00113       TagHT.erase(key);
00114       //gdcmWarningMacro( "One element erased.");
00115       return true;
00116    }
00117 
00118    gdcmWarningMacro( "Key not present");
00119    return false ;
00120 }

bool gdcm::DocEntrySet::SetBinEntry uint8_t *  content,
int  lgth,
BinEntry entry
[inherited]
 

Accesses an existing BinEntry (i.e. a Dicom Element) and modifies it's 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 228 of file gdcmDocEntrySet.cxx.

References gdcm::GDCM_BINLOADED, gdcm::BinEntry::SetBinArea(), gdcm::DocEntry::SetLength(), and gdcm::ContentEntry::SetValue().

00229 {
00230    if(entry)
00231    {
00232       entry->SetBinArea(content);  
00233       entry->SetLength(lgth);
00234       entry->SetValue(GDCM_BINLOADED);
00235       return true;
00236    }
00237    return false;
00238 }

bool gdcm::DocEntrySet::SetBinEntry uint8_t *  content,
int  lgth,
uint16_t  group,
uint16_t  elem
[inherited]
 

Accesses an existing DocEntry (i.e. a Dicom Element) through it's (group, element) and modifies it's 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 191 of file gdcmDocEntrySet.cxx.

References gdcmWarningMacro, and gdcm::DocEntrySet::GetBinEntry().

Referenced by gdcm::DocEntrySet::InsertBinEntry(), and gdcm::FileHelper::SetBinEntry().

00193 {
00194    BinEntry *entry = GetBinEntry(group, elem);
00195    if (!entry )
00196    {
00197       gdcmWarningMacro( "No corresponding ValEntry " << std::hex << group <<
00198                         "," << elem << " element (try promotion first).");
00199       return false;
00200    }
00201 
00202    return SetBinEntry(content,lgth,entry);
00203 } 

void gdcm::Document::SetFileName std::string const &  fileName  )  [inline]
 

Accessor to Filename.

Definition at line 81 of file gdcmDocument.h.

Referenced by gdcm::DicomDir::DicomDir().

00081 { Filename = fileName; }

void gdcm::Document::SetMaxSizeLoadEntry long  newSize  )  [private]
 

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

Parameters:
newSize 

Definition at line 1929 of file gdcmDocument.cxx.

References MaxSizeLoadEntry.

Referenced by Document().

01930 {
01931    if ( newSize < 0 )
01932    {
01933       return;
01934    }
01935    if ((uint32_t)newSize >= (uint32_t)0xffffffff )
01936    {
01937       MaxSizeLoadEntry = 0xffffffff;
01938       return;
01939    }
01940    MaxSizeLoadEntry = newSize;
01941 }

void gdcm::Document::SetMaxSizePrintEntry long  newSize  )  [private]
 

Header Elements too long will not be printed.

Todo:
See comments of Document::MAX_SIZE_PRINT_ELEMENT_VALUE
Parameters:
newSize 

Definition at line 1948 of file gdcmDocument.cxx.

References MaxSizePrintEntry.

01949 {
01950    if ( newSize < 0 )
01951    {
01952       return;
01953    }
01954    if ((uint32_t)newSize >= (uint32_t)0xffffffff )
01955    {
01956       MaxSizePrintEntry = 0xffffffff;
01957       return;
01958    }
01959    MaxSizePrintEntry = newSize;
01960 }

void gdcm::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

Definition at line 45 of file gdcmBase.h.

Referenced by gdcm::SQItem::Print(), gdcm::SeqEntry::Print(), gdcm::FileHelper::Print(), gdcm::ElementSet::Print(), and gdcm::DicomDir::Print().

00045 { PrintLevel = level; };

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

Set the shadow dictionary used.

Parameters:
dictName name of the dictionary to use in shadow

Definition at line 210 of file gdcmDocument.cxx.

References gdcm::DictKey, and RefShaDict.

00211 {
00212    RefShaDict = Global::GetDicts()->GetDict(dictName);
00213    return !RefShaDict;
00214 }

bool gdcm::Document::SetShaDict Dict dict  ) 
 

Set the shadow dictionary used.

Parameters:
dict dictionary to use in shadow

Definition at line 200 of file gdcmDocument.cxx.

References RefShaDict.

00201 {
00202    RefShaDict = dict;
00203    return !RefShaDict;
00204 }

bool gdcm::DocEntrySet::SetValEntry std::string const &  content,
ValEntry entry
[inherited]
 

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

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

Definition at line 211 of file gdcmDocEntrySet.cxx.

References gdcm::ValEntry::SetValue().

00212 {
00213    if(entry)
00214    {
00215       entry->SetValue(content);
00216       return true;
00217    }
00218    return false;
00219 }

bool gdcm::DocEntrySet::SetValEntry std::string const &  content,
uint16_t  group,
uint16_t  elem
[inherited]
 

Accesses an existing DocEntry (i.e. a Dicom Element) through it's (group, element) and modifies it's 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 169 of file gdcmDocEntrySet.cxx.

References gdcmWarningMacro, and gdcm::DocEntrySet::GetValEntry().

Referenced by gdcm::File::AnonymizeFile(), Document(), gdcm::DocEntrySet::InsertValEntry(), gdcm::FileHelper::SetValEntry(), and gdcm::File::Write().

00171 {
00172    ValEntry *entry = GetValEntry(group, elem);
00173    if (!entry )
00174    {
00175       gdcmWarningMacro( "No corresponding ValEntry " << std::hex << group <<
00176                          "," << elem << " element (try promotion first).");
00177       return false;
00178    }
00179    return SetValEntry(content,entry);
00180 }

void gdcm::Document::SkipBytes uint32_t  nBytes  )  [protected]
 

skips bytes inside the source file

Warning:
NOT end user intended method !
Returns:

Definition at line 707 of file gdcmDocument.cxx.

References Fp.

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

00708 {
00709    //FIXME don't dump the returned value
00710    Fp->seekg((long)nBytes, std::ios::cur);
00711 }

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

Skip a given Header Entry.

Warning:
NOT end user intended method !
Parameters:
entry entry to skip

Definition at line 1582 of file gdcmDocument.cxx.

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

01583 {
01584    SkipBytes(entry->GetLength());
01585 }

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

Skips to the beginning of the next Header Entry.

Warning:
NOT end user intended method !
Parameters:
currentDocEntry entry to skip

Definition at line 1592 of file gdcmDocument.cxx.

References Fp, gdcm::DocEntry::GetGroup(), gdcm::DocEntry::GetOffset(), and gdcm::DocEntry::GetReadLength().

Referenced by ParseDES().

01593 {
01594    Fp->seekg((long)(currentDocEntry->GetOffset()),     std::ios::beg);
01595    if (currentDocEntry->GetGroup() != 0xfffe)  // for fffe pb
01596       Fp->seekg( (long)(currentDocEntry->GetReadLength()),std::ios::cur);
01597 }

uint32_t gdcm::Document::SwapLong uint32_t  a  ) 
 

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

Returns:
The properly swaped 32 bits integer.

Definition at line 365 of file gdcmDocument.cxx.

References gdcmErrorMacro, and SwapCode.

Referenced by GetDocEntryValue().

00366 {
00367    switch (SwapCode)
00368    {
00369       case 1234 :
00370          break;
00371       case 4321 :
00372          a=( ((a<<24) & 0xff000000) | ((a<<8)  & 0x00ff0000) | 
00373              ((a>>8)  & 0x0000ff00) | ((a>>24) & 0x000000ff) );
00374          break;   
00375       case 3412 :
00376          a=( ((a<<16) & 0xffff0000) | ((a>>16) & 0x0000ffff) );
00377          break;  
00378       case 2143 :
00379          a=( ((a<< 8) & 0xff00ff00) | ((a>>8) & 0x00ff00ff)  );
00380       break;
00381       default :
00382          gdcmErrorMacro( "Unset swap code:" << SwapCode );
00383          a = 0;
00384    }
00385    return a;
00386 } 

uint16_t gdcm::Document::SwapShort uint16_t  a  ) 
 

Swaps the bytes so they agree with the processor order.

Returns:
The properly swaped 16 bits integer.

Definition at line 351 of file gdcmDocument.cxx.

References SwapCode.

Referenced by GetDocEntryValue(), and HandleOutOfGroup0002().

00352 {
00353    if ( SwapCode == 4321 || SwapCode == 2143 )
00354    {
00355       a = ((( a << 8 ) & 0xff00 ) | (( a >> 8 ) & 0x00ff ) );
00356    }
00357    return a;
00358 }

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

Change the Byte Swap code.

Definition at line 1904 of file gdcmDocument.cxx.

References gdcmWarningMacro, and SwapCode.

Referenced by HandleBrokenEndian(), and HandleOutOfGroup0002().

01905 {
01906    gdcmWarningMacro( "Switching Byte Swap code from "<< SwapCode);
01907    if ( SwapCode == 1234 ) 
01908    {
01909       SwapCode = 4321;
01910    }
01911    else if ( SwapCode == 4321 ) 
01912    {
01913       SwapCode = 1234;
01914    }
01915    else if ( SwapCode == 3412 ) 
01916    {
01917       SwapCode = 2143;
01918    }
01919    else if ( SwapCode == 2143 )
01920    {
01921       SwapCode = 3412;
01922    }
01923 }

uint32_t gdcm::Document::UnswapLong uint32_t  a  )  [inline]
 

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

Definition at line 75 of file gdcmDocument.h.

00075 { return SwapLong(a);}

uint16_t gdcm::Document::UnswapShort uint16_t  a  )  [inline]
 

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

Definition at line 72 of file gdcmDocument.h.

00072 { return SwapShort(a);}

void gdcm::Document::WriteContent std::ofstream *  fp,
FileType  filetype
[virtual]
 

Writes in a file all the Header 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)
Returns:
Always true.

Reimplemented from gdcm::ElementSet.

Definition at line 482 of file gdcmDocument.cxx.

References gdcm::ExplicitVR, and gdcm::ImplicitVR.

00483 {
00484    // \TODO move the following lines (and a lot of others, to be written)
00485    // to a future function CheckAndCorrectHeader  
00486 
00487    // (necessary if user wants to write a DICOM V3 file
00488    // starting from an ACR-NEMA (V2) Header
00489 
00490    if ( filetype == ImplicitVR || filetype == ExplicitVR )
00491    {
00492       // writing Dicom File Preamble
00493       char filePreamble[128];
00494       memset(filePreamble, 0, 128);
00495       fp->write(filePreamble, 128);
00496       fp->write("DICM", 4);
00497    }
00498 
00499    /*
00500     * \todo rewrite later, if really usefull
00501     *       - 'Group Length' element is optional in DICOM
00502     *       - but un-updated odd groups lengthes can causes pb
00503     *         (xmedcon breaker)
00504     *
00505     * if ( (filetype == ImplicitVR) || (filetype == ExplicitVR) )
00506     *    UpdateGroupLength(false,filetype);
00507     * if ( filetype == ACR)
00508     *    UpdateGroupLength(true,ACR);
00509     */
00510 
00511    ElementSet::WriteContent(fp, filetype); // This one is recursive
00512 }


Member Data Documentation

ListElements gdcm::Document::AnonymizeList [protected]
 

List of element to Anonymize.

Definition at line 150 of file gdcmDocument.h.

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

Refering underlying filename.

Definition at line 112 of file gdcmDocument.h.

FileType gdcm::Document::Filetype [protected]
 

ACR, ACR_LIBIDO, ExplicitVR, ImplicitVR, Unknown.

Definition at line 138 of file gdcmDocument.h.

Referenced by CheckSwap(), Document(), FindDocEntryVR(), GetFileType(), HandleOutOfGroup0002(), Initialize(), IsReadable(), ParseDES(), and ReadNextDocEntry().

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

File Pointer, opened during Document parsing.

Definition at line 135 of file gdcmDocument.h.

Referenced by CheckSwap(), CloseFile(), Document(), FindDocEntryVR(), IsDocEntryAnInteger(), LoadDocEntry(), LoadDocEntrySafe(), LoadEntryBinArea(), OpenFile(), ParseDES(), ParseSQ(), ReadNextDocEntry(), SkipBytes(), and SkipToNextDocEntry().

bool gdcm::Document::Group0002Parsed [protected]
 

whether we already parsed group 0002 (Meta Elements)

Definition at line 129 of file gdcmDocument.h.

Referenced by Document(), and HandleOutOfGroup0002().

bool gdcm::Document::HasDCMPreamble [protected]
 

whether file has a DCM Preamble

Definition at line 132 of file gdcmDocument.h.

Referenced by OpenFile(), and ReadNextDocEntry().

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

After opening the file, we read HEADER_LENGTH_TO_READ bytes.

Definition at line 141 of file gdcmDocument.h.

const unsigned int gdcm::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 51 of file gdcmDocument.cxx.

Referenced by Document().

const unsigned int gdcm::Document::MAX_SIZE_PRINT_ELEMENT_VALUE = 0x7fffffff [static, protected]
 

Elements whose value is longer than MAX_SIZE_PRINT_ELEMENT_VALUE are NOT printed.

Definition at line 52 of file gdcmDocument.cxx.

uint32_t gdcm::Document::MaxSizeLoadEntry [private]
 

Size threshold above which an element value will NOT be loaded in memory (to avoid loading the image/volume itself). By default, this upper bound is fixed to 1024 bytes (which might look reasonable when one considers the definition of the various VR contents).

Definition at line 197 of file gdcmDocument.h.

Referenced by LoadDocEntry(), and SetMaxSizeLoadEntry().

uint32_t gdcm::Document::MaxSizePrintEntry [private]
 

Size threshold above which an element value will NOT be *printed* in order no to polute the screen output. By default, this upper bound is fixed to 64 bytes.

Definition at line 202 of file gdcmDocument.h.

Referenced by SetMaxSizePrintEntry().

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

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

Definition at line 53 of file gdcmBase.h.

Referenced by gdcm::Base::Base().

Dict* gdcm::Document::RefPubDict [private]
 

Public dictionary used to parse this header.

Definition at line 188 of file gdcmDocument.h.

Referenced by GetPubDict(), Initialize(), and ~Document().

Dict* gdcm::Document::RefShaDict [private]
 

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

Definition at line 191 of file gdcmDocument.h.

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

int gdcm::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 126 of file gdcmDocument.h.

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


The documentation for this class was generated from the following files:
Generated on Thu Feb 10 22:18:08 2005 for gdcm by doxygen 1.3.6