+2003-04-16 Eric Boix <Eric.Boix@creatis.insa-lyon.fr> with JPR
+ * More memmory link related corrections and documentation fixes.
+
2003-04-15 Eric Boix <Eric.Boix@creatis.insa-lyon.fr> with JPR
- * Memory link hunt (by using valgrind --leak-check=yes PrintHeader).
+ * Memory link hunt (by using valgrind through the command
+ valgrind --show-reachable=yes --leak-check=yes PrintHeader).
- added src/gdcmVR.cxx gdcmVR.h that objectify the previous
gdcmHeader::_dicom_vr.
- gdcmHeader::InitVRDict transfered as gdcmVR::gdcmVR().
bug1
image.dcm
image.raw
+test2.acr.dcm
+test2.acr.raw
+test3.acr.dcm
+test3.acr.raw
#include "gdcmDict.h"
#include "gdcmUtil.h"
-gdcmDict::gdcmDict(const char* FileName) {
- std::ifstream from(FileName);
- dbg.Error(!from, "gdcmDict::gdcmDict: can't open dictionary", FileName);
+/**
+ * \ingroup gdcmDict
+ * \brief Construtor
+ * @param FileName from which to build the dictionary.
+ */
+gdcmDict::gdcmDict(string & FileName) {
+ std::ifstream from(FileName.c_str());
+ dbg.Error(!from, "gdcmDict::gdcmDict: can't open dictionary",
+ FileName.c_str());
guint16 group, element;
// CLEANME : use defines for all those constants
char buff[1024];
name = buff;
gdcmDictEntry * newEntry = new gdcmDictEntry(group, element,
vr, fourth, name);
+ // FIXME: use AddNewEntry
NameHt[name] = newEntry;
KeyHt[gdcmDictEntry::TranslateToKey(group, element)] = newEntry;
}
from.close();
}
+gdcmDict::~gdcmDict() {
+ for (TagKeyHT::iterator tag = KeyHt.begin(); tag != KeyHt.end(); ++tag) {
+ gdcmDictEntry* EntryToDelete = tag->second;
+ if ( EntryToDelete )
+ delete EntryToDelete;
+ }
+ KeyHt.clear();
+ // Since AddNewEntry adds symetrical in both KeyHt and NameHT we can
+ // assume all the pointed gdcmDictEntries are allready cleaned-up when
+ // we cleaned KeyHt.
+ NameHt.clear();
+}
+
void gdcmDict::Print(ostream& os) {
PrintByKey(os);
}
/**
- * \ingroup gdcmHeader
+ * \ingroup gdcmDict
* \brief Print all the dictionary entries contained in this dictionary.
* Entries will be sorted by tag i.e. the couple (group, element).
* @param os The output stream to be written to.
}
/**
- * \ingroup gdcmHeader
+ * \ingroup gdcmDict
* \brief Print all the dictionary entries contained in this dictionary.
* Entries will be sorted by the name of the dictionary entries.
* @param os The output stream to be written to.
}
/**
- * \ingroup gdcmHeader
+ * \ingroup gdcmDict
* \brief Get the dictionnary entry identified by a given tag (group,element)
* @param group group of the entry to be found
* @param element element of the entry to be found
}
/**
- * \ingroup gdcmHeader
+ * \ingroup gdcmDict
* \brief Get the dictionnary entry identified by it's name.
* @param name element of the ElVal to modify
* @return the corresponding dictionnary entry when existing, NULL otherwise
int gdcmDict::RemoveEntry(TagKey key) {
if(KeyHt.count(key) == 1) {
+ gdcmDictEntry* EntryToDelete = KeyHt.find(key)->second;
+ if ( EntryToDelete )
+ delete EntryToDelete;
KeyHt.erase(key);
return (1);
} else {
typedef map<TagKey, gdcmDictEntry*> TagKeyHT;
typedef map<TagName, gdcmDictEntry*> TagNameHT;
+/// Build a memory representation of a dicom dictionary by parsing
+/// an ascii file
class GDCM_EXPORT gdcmDict {
string name;
string filename;
- TagKeyHT KeyHt; // Both accesses with a TagKey or with a
- TagNameHT NameHt; // TagName are required.
+ /// Access through TagKey (see alternate access with NameHt)
+ TagKeyHT KeyHt;
+ /// Access through TagName (see alternate access with KeyHt)
+ TagNameHT NameHt;
public:
- gdcmDict(const char* FileName); // Reads Dict from ascii file
+ gdcmDict(string & FileName);
+ ~gdcmDict();
int AddNewEntry (gdcmDictEntry* NewEntry);
int ReplaceEntry(gdcmDictEntry* NewEntry);
int RemoveEntry (TagKey key);
gdcmDictEntry::gdcmDictEntry(guint16 InGroup, guint16 InElement,
- string InVr, string InFourth, string InName) {
+ string InVr, string InFourth,
+ string InName) {
group = InGroup;
element = InElement;
vr = InVr;
#endif
#define PUB_DICT_FILENAME "dicomV3.dic"
-string gdcmDictSet::DictPath = gdcmDictSet::BuildDictPath();
-gdcmDict* gdcmDictSet::DefaultPubDict = gdcmDictSet::LoadDefaultPubDict();
-
/**
* \ingroup gdcmDictSet
* \brief Consider all the entries of the public dicom dictionnary.
*/
list<string> * gdcmDictSet::GetPubDictTagNames(void) {
list<string> * Result = new list<string>;
- TagKeyHT entries = gdcmDictSet::DefaultPubDict->GetEntries();
+ TagKeyHT entries = GetDefaultPubDict()->GetEntries();
for (TagKeyHT::iterator tag = entries.begin(); tag != entries.end(); ++tag){
Result->push_back( tag->second->GetName() );
*/
map<string, list<string> > * gdcmDictSet::GetPubDictTagNamesByCategory(void) {
map<string, list<string> > * Result = new map<string, list<string> >;
- TagKeyHT entries = gdcmDictSet::DefaultPubDict->GetEntries();
+ TagKeyHT entries = GetDefaultPubDict()->GetEntries();
for (TagKeyHT::iterator tag = entries.begin(); tag != entries.end(); ++tag){
(*Result)[tag->second->GetFourth()].push_back(tag->second->GetName());
return ResultPath;
}
-/**
- * \ingroup gdcmDictSet
- * \brief Loads the default public DICOM V3 dictionary as a gdcmDict.
- * \return The newly build reference public dictionary.
- */
-gdcmDict* gdcmDictSet::LoadDefaultPubDict(void) {
- string PubDictFile = gdcmDictSet::DictPath + PUB_DICT_FILENAME;
- return new gdcmDict(PubDictFile.c_str());
-}
-
/**
* \ingroup gdcmDictSet
* \brief The Dictionnary Set obtained with this constructor simply
* contains the Default Public dictionnary.
*/
gdcmDictSet::gdcmDictSet(void) {
- dicts[PUB_DICT_NAME] = DefaultPubDict;
+ DictPath = BuildDictPath();
+ string PubDictFile = DictPath + PUB_DICT_FILENAME;
+ Dicts[PUB_DICT_NAME] = new gdcmDict(PubDictFile);
}
gdcmDictSet::~gdcmDictSet() {
- //FIXME : first destroy pointed dictionaries before trashing hash table.
- dicts.clear();
+ for (DictSetHT::iterator tag = Dicts.begin(); tag != Dicts.end(); ++tag) {
+ gdcmDict* EntryToDelete = tag->second;
+ if ( EntryToDelete )
+ delete EntryToDelete;
+ }
+ Dicts.clear();
}
/**
* created dictionary.
*/
void gdcmDictSet::LoadDictFromFile(string FileName, DictKey Name) {
- gdcmDict *NewDict = new gdcmDict(FileName.c_str());
- dicts[Name] = NewDict;
+ gdcmDict *NewDict = new gdcmDict(FileName);
+ Dicts[Name] = NewDict;
}
/**
* @param os Output stream used for printing.
*/
void gdcmDictSet::Print(ostream& os) {
- for (DictSetHT::iterator dict = dicts.begin(); dict != dicts.end(); ++dict){
+ for (DictSetHT::iterator dict = Dicts.begin(); dict != Dicts.end(); ++dict){
os << "Printing dictionary " << dict->first << " \n";
dict->second->Print(os);
}
* \result The retrieved dictionary.
*/
gdcmDict * gdcmDictSet::GetDict(DictKey DictName) {
- DictSetHT::iterator dict = dicts.find(DictName);
+ DictSetHT::iterator dict = Dicts.find(DictName);
return dict->second;
}
*/
class GDCM_EXPORT gdcmDictSet {
private:
- DictSetHT dicts;
+ /// Hash table of all dictionaries contained in this gdcmDictSet
+ DictSetHT Dicts;
+ /// Directory path to dictionaries
+ string DictPath;
int AppendDict(gdcmDict* NewDict);
void LoadDictFromFile(string filename, DictKey);
-private:
- /// Directory path to dictionaries
- static string DictPath;
- static string BuildDictPath(void);
- static gdcmDict* DefaultPubDict;
+ string BuildDictPath(void);
public:
- static list<string> * GetPubDictTagNames(void);
- static map<string, list<string> >* GetPubDictTagNamesByCategory(void);
- static gdcmDict* LoadDefaultPubDict(void);
+ list<string> * GetPubDictTagNames(void);
+ map<string, list<string> >* GetPubDictTagNamesByCategory(void);
// TODO Swig int LoadDictFromFile(string filename);
// QUESTION: the following function might not be thread safe !? Maybe
#include "gdcmUtil.h"
#include "gdcmElValSet.h"
+gdcmElValSet::~gdcmElValSet() {
+ for (TagElValueHT::iterator tag = tagHt.begin(); tag != tagHt.end(); ++tag) {
+ gdcmElValue* EntryToDelete = tag->second;
+ if ( EntryToDelete )
+ delete EntryToDelete;
+ }
+ tagHt.clear();
+ // Since Add() adds symetrical in both tagHt and NameHt we can
+ // assume all the pointed gdcmElValues are allready cleaned-up when
+ // we cleaned tagHt.
+ NameHt.clear();
+}
TagElValueHT & gdcmElValSet::GetTagHt(void) {
return tagHt;
}
continue;
}
+ tokens.clear();
// Les pixels ne sont pas chargés dans l'element !
if ((gr == 0x7fe0) && (el == 0x0010) ) break;
-// $Header: /cvs/public/gdcm/src/Attic/gdcmElValSet.h,v 1.10 2003/04/09 14:04:53 jpr Exp $
+// $Header: /cvs/public/gdcm/src/Attic/gdcmElValSet.h,v 1.11 2003/04/16 08:03:27 frog Exp $
#ifndef GDCMELVALSET_H
#define GDCMELVALSET_H
typedef map<GroupKey, int> GroupHT;
public:
+ ~gdcmElValSet();
void Add(gdcmElValue*);
void Print(ostream &);
#define _MaxSizeLoadElementValue_ 1024
gdcmVR * gdcmHeader::dicom_vr = (gdcmVR*)0;
+gdcmDictSet * gdcmHeader::Dicts = (gdcmDictSet*)0;
void gdcmHeader::Initialise(void) {
if (!gdcmHeader::dicom_vr)
gdcmHeader::dicom_vr = gdcmGlobal::GetVR();
- Dicts = new gdcmDictSet();
+ if (!gdcmHeader::Dicts)
+ gdcmHeader::Dicts = gdcmGlobal::GetDicts();
RefPubDict = Dicts->GetDefaultPubDict();
RefShaDict = (gdcmDict*)0;
}
}
gdcmHeader::~gdcmHeader (void) {
- delete Dicts;
- //FIXME obviously there is much to be done here !
+ dicom_vr = (gdcmVR*)0;
+ Dicts = (gdcmDictSet*)0;
+ RefPubDict = (gdcmDict*)0;
+ RefShaDict = (gdcmDict*)0;
return;
}
static gdcmVR *dicom_vr;
/// Global dictionary container
- gdcmDictSet* Dicts;
+ static gdcmDictSet* Dicts;
/// Public dictionary used to parse this header
gdcmDict* RefPubDict;
/// Optional "shadow dictionary" (private elements) used to parse this
// Library globals.
gdcmDebug dbg;
-gdcmVR * gdcmGlobal::VR = new gdcmVR();
gdcmDebug::gdcmDebug(int level) {
DebugLevel = level;
}
///////////////////////////////////////////////////////////////////////////
+gdcmVR * gdcmGlobal::VR = (gdcmVR*)0;
+gdcmDictSet * gdcmGlobal::Dicts = (gdcmDictSet*)0;
+gdcmGlobal gdcmGlob;
+
gdcmGlobal::gdcmGlobal(void) {
+ if (VR || Dicts)
+ dbg.Verbose(0, "gdcmGlobal::gdcmGlobal: VR or Dicts allready allocated");
+ VR = new gdcmVR();
+ Dicts = new gdcmDictSet();
}
-gdcmGlobal::~gdcmGlobal(void) {
+gdcmGlobal::~gdcmGlobal() {
delete VR;
+ delete Dicts;
}
gdcmVR * gdcmGlobal::GetVR(void) {
return VR;
}
+gdcmDictSet * gdcmGlobal::GetDicts(void) {
+ return Dicts;
+}
+
///////////////////////////////////////////////////////////////////////////
// Because is not yet available in g++2.96
istream& eatwhite(istream& is) {
#include <vector>
#include <string>
#include "gdcmVR.h"
+#include "gdcmDictSet.h"
using namespace std;
class gdcmDebug {
class gdcmGlobal {
private:
static gdcmVR *VR;
+ static gdcmDictSet *Dicts;
public:
gdcmGlobal(void);
- ~gdcmGlobal(void);
+ ~gdcmGlobal();
static gdcmVR * GetVR(void);
+ static gdcmDictSet * GetDicts(void);
};
istream & eatwhite(istream & is);
// gdcmVR.cxx
#include "gdcmVR.h"
-#include "gdcmUtil.h"
-gdcmVR::gdcmVR () {
- // NOTE: making the affectation directely to dicom_vr instead of passing
- // through an apparently unncessary local variable vr, crashes with
- // gcc... Beware.
- VRHT *vr = new VRHT;
- (*vr)["AE"] = "Application Entity"; // At most 16 bytes
- (*vr)["AS"] = "Age String"; // Exactly 4 bytes
- (*vr)["AT"] = "Attribute Tag"; // 2 16-bit unsigned short integers
- (*vr)["CS"] = "Code String"; // At most 16 bytes
- (*vr)["DA"] = "Date"; // Exactly 8 bytes
- (*vr)["DS"] = "Decimal String"; // At most 16 bytes
- (*vr)["DT"] = "Date Time"; // At most 26 bytes
- (*vr)["FL"] = "Floating Point Single"; // 32-bit IEEE 754:1985 float
- (*vr)["FD"] = "Floating Point Double"; // 64-bit IEEE 754:1985 double
- (*vr)["IS"] = "Integer String"; // At most 12 bytes
- (*vr)["LO"] = "Long String"; // At most 64 chars
- (*vr)["LT"] = "Long Text"; // At most 10240 chars
- (*vr)["OB"] = "Other Byte String"; // String of bytes (vr independant)
- (*vr)["OW"] = "Other Word String"; // String of 16-bit words (vr dep)
- (*vr)["PN"] = "Person Name"; // At most 64 chars
- (*vr)["SH"] = "Short String"; // At most 16 chars
- (*vr)["SL"] = "Signed Long"; // Exactly 4 bytes
- (*vr)["SQ"] = "Sequence of Items"; // Not Applicable
- (*vr)["SS"] = "Signed Short"; // Exactly 2 bytes
- (*vr)["ST"] = "Short Text"; // At most 1024 chars
- (*vr)["TM"] = "Time"; // At most 16 bytes
- (*vr)["UI"] = "Unique Identifier"; // At most 64 bytes
- (*vr)["UL"] = "Unsigned Long "; // Exactly 4 bytes
- (*vr)["UN"] = "Unknown"; // Any length of bytes
- (*vr)["US"] = "Unsigned Short "; // Exactly 2 bytes
- (*vr)["UT"] = "Unlimited Text"; // At most 2^32 -1 chars
- dicom_vr = vr;
+gdcmVR::gdcmVR(void) {
+ vr["AE"] = "Application Entity"; // At most 16 bytes
+ vr["AS"] = "Age String"; // Exactly 4 bytes
+ vr["AT"] = "Attribute Tag"; // 2 16-bit unsigned short integers
+ vr["CS"] = "Code String"; // At most 16 bytes
+ vr["DA"] = "Date"; // Exactly 8 bytes
+ vr["DS"] = "Decimal String"; // At most 16 bytes
+ vr["DT"] = "Date Time"; // At most 26 bytes
+ vr["FL"] = "Floating Point Single"; // 32-bit IEEE 754:1985 float
+ vr["FD"] = "Floating Point Double"; // 64-bit IEEE 754:1985 double
+ vr["IS"] = "Integer String"; // At most 12 bytes
+ vr["LO"] = "Long String"; // At most 64 chars
+ vr["LT"] = "Long Text"; // At most 10240 chars
+ vr["OB"] = "Other Byte String"; // String of bytes (vr independant)
+ vr["OW"] = "Other Word String"; // String of 16-bit words (vr dep)
+ vr["PN"] = "Person Name"; // At most 64 chars
+ vr["SH"] = "Short String"; // At most 16 chars
+ vr["SL"] = "Signed Long"; // Exactly 4 bytes
+ vr["SQ"] = "Sequence of Items"; // Not Applicable
+ vr["SS"] = "Signed Short"; // Exactly 2 bytes
+ vr["ST"] = "Short Text"; // At most 1024 chars
+ vr["TM"] = "Time"; // At most 16 bytes
+ vr["UI"] = "Unique Identifier"; // At most 64 bytes
+ vr["UL"] = "Unsigned Long "; // Exactly 4 bytes
+ vr["UN"] = "Unknown"; // Any length of bytes
+ vr["US"] = "Unsigned Short "; // Exactly 2 bytes
+ vr["UT"] = "Unlimited Text"; // At most 2^32 -1 chars
}
gdcmVR::~gdcmVR() {
- dicom_vr->clear();
- delete dicom_vr;
+ vr.clear();
}
int gdcmVR::Count(VRKey key) {
- return dicom_vr->count(key);
+ return vr.count(key);
}
typedef string VRAtr;
typedef map<VRKey, VRAtr> VRHT; // Value Representation Hash Table
-/*
- * \defgroup gdcmVR
- * \brief Container for dicom Value Representation Hash Table
- * \note This is a singleton
- */
+/// Container for dicom Value Representation Hash Table
+/// \note This is a singleton
class GDCM_EXPORT gdcmVR {
private:
- VRHT *dicom_vr;
+ VRHT vr;
public:
- gdcmVR();
+ gdcmVR(void);
~gdcmVR();
- int Count(VRKey);
+ int Count(VRKey key);
};
#endif