From 74917aa3a592bde592130de5ece8d9315015b373 Mon Sep 17 00:00:00 2001 From: regrain Date: Thu, 15 Jan 2004 16:36:28 +0000 Subject: [PATCH] * src/gdcmDicSet.[h|cxx] : add virtual entries to have a reference of entries created while parsing the header. Thus, they will be destroyed when the gdcmDictSet will be destroyed * src/gdcmHeader.cxx, gdcmHeaderEntrySet.cxx : uses virtual entries of gdcmDictSet -- BeNours --- ChangeLog | 7 +++ src/gdcmDictSet.cxx | 100 +++++++++++++++++++++++++++++-------- src/gdcmDictSet.h | 13 +++-- src/gdcmHeader.cxx | 10 ++-- src/gdcmHeaderEntrySet.cxx | 2 +- 5 files changed, 101 insertions(+), 31 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9eb2c49f..d9a35b9c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2004-01-15 Benoit Regrain + * src/gdcmDicSet.[h|cxx] : add virtual entries to have a reference of + entries created while parsing the header. Thus, they will be destroyed + when the gdcmDictSet will be destroyed + * src/gdcmHeader.cxx, gdcmHeaderEntrySet.cxx : uses virtual entries of + gdcmDictSet + 2004-01-15 Benoit Regrain * vtk/vtkGdcmReader.cxx : bug fix : before, with python only, the program made a fatal error because of the memory release at the end of program. diff --git a/src/gdcmDictSet.cxx b/src/gdcmDictSet.cxx index ce08aa50..fe95d73a 100644 --- a/src/gdcmDictSet.cxx +++ b/src/gdcmDictSet.cxx @@ -18,7 +18,8 @@ * \brief The Dictionnary Set obtained with this constructor simply * contains the Default Public dictionnary. */ -gdcmDictSet::gdcmDictSet(void) { +gdcmDictSet::gdcmDictSet(void) +{ DictPath = BuildDictPath(); std::string PubDictFile = DictPath + PUB_DICT_FILENAME; Dicts[PUB_DICT_NAME] = new gdcmDict(PubDictFile); @@ -28,13 +29,27 @@ gdcmDictSet::gdcmDictSet(void) { * \ingroup gdcmDictSet * \brief Destructor */ -gdcmDictSet::~gdcmDictSet() { - for (DictSetHT::iterator tag = Dicts.begin(); tag != Dicts.end(); ++tag) { - gdcmDict* EntryToDelete = tag->second; +gdcmDictSet::~gdcmDictSet() +{ + // Remove dictionnaries + for (DictSetHT::iterator tag = Dicts.begin(); tag != Dicts.end(); ++tag) + { + gdcmDict *EntryToDelete = tag->second; if ( EntryToDelete ) delete EntryToDelete; + tag->second=NULL; } Dicts.clear(); + + // Remove virtual dictionnary entries + std::map::iterator it; + for(it=virtualEntry.begin(); it!=virtualEntry.end(); ++it) + { + gdcmDictEntry *Entry = it->second; + if ( Entry ) + delete Entry; + it->second=NULL; + } } //----------------------------------------------------------------------------- @@ -45,8 +60,10 @@ gdcmDictSet::~gdcmDictSet() { * contained is this gdcmDictSet, along with their respective content. * @param os Output stream used for printing. */ -void gdcmDictSet::Print(std::ostream& os) { - for (DictSetHT::iterator dict = Dicts.begin(); dict != Dicts.end(); ++dict){ +void gdcmDictSet::Print(std::ostream& os) +{ + for (DictSetHT::iterator dict = Dicts.begin(); dict != Dicts.end(); ++dict) + { os << "Printing dictionary " << dict->first << std::endl; dict->second->Print(os); } @@ -61,11 +78,13 @@ void gdcmDictSet::Print(std::ostream& os) { * \sa gdcmDictSet::GetPubDictTagNamesByCategory * @return A list of all entries of the public dicom dictionnary. */ -std::list * gdcmDictSet::GetPubDictTagNames(void) { - std::list * Result = new std::list; +std::list *gdcmDictSet::GetPubDictTagNames(void) +{ + std::list *Result = new std::list; TagKeyHT entries = GetDefaultPubDict()->GetEntries(); - for (TagKeyHT::iterator tag = entries.begin(); tag != entries.end(); ++tag){ + for (TagKeyHT::iterator tag = entries.begin(); tag != entries.end(); ++tag) + { Result->push_back( tag->second->GetName() ); } return Result; @@ -95,11 +114,13 @@ std::list * gdcmDictSet::GetPubDictTagNames(void) { * corresponding values are lists of all the dictionnary entries * among that group. */ -std::map > * gdcmDictSet::GetPubDictTagNamesByCategory(void) { - std::map > * Result = new std::map >; +std::map > *gdcmDictSet::GetPubDictTagNamesByCategory(void) +{ + std::map > *Result = new std::map >; TagKeyHT entries = GetDefaultPubDict()->GetEntries(); - for (TagKeyHT::iterator tag = entries.begin(); tag != entries.end(); ++tag){ + for (TagKeyHT::iterator tag = entries.begin(); tag != entries.end(); ++tag) + { (*Result)[tag->second->GetFourth()].push_back(tag->second->GetName()); } return Result; @@ -114,7 +135,8 @@ std::map > * gdcmDictSet::GetPubDictTagNames * @param Name Symbolic name that be used as identifier of the newly * created dictionary. */ -void gdcmDictSet::LoadDictFromFile(std::string FileName, DictKey Name) { +void gdcmDictSet::LoadDictFromFile(std::string FileName, DictKey Name) +{ gdcmDict *NewDict = new gdcmDict(FileName); AppendDict(NewDict,Name); } @@ -126,9 +148,12 @@ void gdcmDictSet::LoadDictFromFile(std::string FileName, DictKey Name) { * @param DictName The symbolic name of the searched dictionary. * \result The retrieved dictionary. */ -gdcmDict * gdcmDictSet::GetDict(DictKey DictName) { +gdcmDict *gdcmDictSet::GetDict(DictKey DictName) +{ DictSetHT::iterator dict = Dicts.find(DictName); - return dict->second; + if(dict!=Dicts.end()) + return dict->second; + return NULL; } /** @@ -136,36 +161,67 @@ gdcmDict * gdcmDictSet::GetDict(DictKey DictName) { * \brief Retrieve the default reference DICOM V3 public dictionary. * \result The retrieved default dictionary. */ -gdcmDict * gdcmDictSet::GetDefaultPubDict() { +gdcmDict *gdcmDictSet::GetDefaultPubDict() +{ return GetDict(PUB_DICT_NAME); } +/** + * \ingroup gdcmDictSet + * \brief Create a gdcmDictEntry which will be reference + * in no dictionnary + * @return virtual entry + */ +gdcmDictEntry *gdcmDictSet::NewVirtualDictEntry(guint16 group, guint16 element, + std::string vr,std::string fourth, + std::string name) +{ + gdcmDictEntry *entry; + std::string tag=gdcmDictEntry::TranslateToKey(group,element)+vr; + std::map::iterator it; + + it=virtualEntry.find(tag); + if(it!=virtualEntry.end()) + { + entry=it->second; + } + else + { + entry=new gdcmDictEntry(group,element,vr,fourth,name); + virtualEntry[tag]=entry; + } + return(entry); +} + /** * \ingroup gdcmDictSet * \brief Obtain from the GDCM_DICT_PATH environnement variable the * path to directory containing the dictionnaries. When * the environnement variable is absent the path is defaulted * to "../Dicts/". - * @return path to directory containing the dictionnaries + * @return path to directory containing the dictionnaries */ -std::string gdcmDictSet::BuildDictPath(void) { +std::string gdcmDictSet::BuildDictPath(void) +{ std::string ResultPath; - const char* EnvPath = (char*)0; + const char *EnvPath = (char*)0; EnvPath = getenv("GDCM_DICT_PATH"); - if (EnvPath && (strlen(EnvPath) != 0)) { + if (EnvPath && (strlen(EnvPath) != 0)) + { ResultPath = EnvPath; if (ResultPath[ResultPath.length() -1] != '/' ) ResultPath += '/'; dbg.Verbose(1, "gdcmDictSet::BuildDictPath:", "Dictionary path set from environnement"); - } else + } + else ResultPath = PUB_DICT_PATH; return ResultPath; } //----------------------------------------------------------------------------- // Protected -bool gdcmDictSet::AppendDict(gdcmDict* NewDict,DictKey Name) +bool gdcmDictSet::AppendDict(gdcmDict *NewDict,DictKey Name) { Dicts[Name] = NewDict; return(true); diff --git a/src/gdcmDictSet.h b/src/gdcmDictSet.h index 5ca9cad5..86abe1cd 100644 --- a/src/gdcmDictSet.h +++ b/src/gdcmDictSet.h @@ -39,19 +39,26 @@ public: void LoadDictFromFile(std::string FileName, DictKey Name); - gdcmDict* GetDict(DictKey DictName); - gdcmDict* GetDefaultPubDict(void); + gdcmDict *GetDict(DictKey DictName); + gdcmDict *GetDefaultPubDict(void); + + gdcmDictEntry *NewVirtualDictEntry(guint16 group, guint16 element, + std::string vr = "Unknown", + std::string fourth = "Unknown", + std::string name = "Unknown"); static std::string BuildDictPath(void); protected: - bool AppendDict(gdcmDict* NewDict,DictKey Name); + bool AppendDict(gdcmDict *NewDict,DictKey Name); private: /// Hash table of all dictionaries contained in this gdcmDictSet DictSetHT Dicts; /// Directory path to dictionaries std::string DictPath; + + std::map virtualEntry; }; //----------------------------------------------------------------------------- diff --git a/src/gdcmHeader.cxx b/src/gdcmHeader.cxx index 581c605f..e6177650 100644 --- a/src/gdcmHeader.cxx +++ b/src/gdcmHeader.cxx @@ -1662,7 +1662,7 @@ void gdcmHeader::LoadHeaderEntrySafe(gdcmHeaderEntry * entry) { CorrectElem); if (!NewTag) { // This correct tag is not in the dictionary. Create a new one. - NewTag = new gdcmDictEntry(CorrectGroup, CorrectElem); + NewTag = Dicts->NewVirtualDictEntry(CorrectGroup, CorrectElem); } // FIXME this can create a memory leaks on the old entry that be // left unreferenced. @@ -1752,7 +1752,7 @@ void gdcmHeader::FindHeaderEntryVR( gdcmHeaderEntry *ElVal) { // be unwise to overwrite the VR of a dictionary (since it would // compromise it's next user), we need to clone the actual DictEntry // and change the VR for the read one. - gdcmDictEntry* NewTag = new gdcmDictEntry(ElVal->GetGroup(), + gdcmDictEntry* NewTag = Dicts->NewVirtualDictEntry(ElVal->GetGroup(), ElVal->GetElement(), vr, "FIXME", @@ -2316,7 +2316,7 @@ gdcmHeaderEntry* gdcmHeader::NewHeaderEntryByName(std::string Name) { gdcmDictEntry * NewTag = GetDictEntryByName(Name); if (!NewTag) - NewTag = new gdcmDictEntry(0xffff, 0xffff, "LO", "Unknown", Name); + NewTag = Dicts->NewVirtualDictEntry(0xffff, 0xffff, "LO", "Unknown", Name); gdcmHeaderEntry* NewElVal = new gdcmHeaderEntry(NewTag); if (!NewElVal) { @@ -2339,7 +2339,7 @@ gdcmHeaderEntry* gdcmHeader::NewHeaderEntryByNumber(guint16 Group, guint16 Elem) // Find out if the tag we encountered is in the dictionaries: gdcmDictEntry * NewTag = GetDictEntryByNumber(Group, Elem); if (!NewTag) - NewTag = new gdcmDictEntry(Group, Elem); + NewTag = Dicts->NewVirtualDictEntry(Group, Elem); gdcmHeaderEntry* NewElVal = new gdcmHeaderEntry(NewTag); if (!NewElVal) { @@ -2373,7 +2373,7 @@ gdcmHeaderEntry* gdcmHeader::NewManualHeaderEntryToPubDict(std::string NewTagNam "Group 0xffff in Public Dict is full"); return (gdcmHeaderEntry*)0; } - NewEntry = new gdcmDictEntry(StuffGroup, FreeElem, + NewEntry = Dicts->NewVirtualDictEntry(StuffGroup, FreeElem, VR, "GDCM", NewTagName); NewElVal = new gdcmHeaderEntry(NewEntry); PubEntrySet.Add(NewElVal); diff --git a/src/gdcmHeaderEntrySet.cxx b/src/gdcmHeaderEntrySet.cxx index 5b8408a7..b83a4e87 100644 --- a/src/gdcmHeaderEntrySet.cxx +++ b/src/gdcmHeaderEntrySet.cxx @@ -428,7 +428,7 @@ void gdcmHeaderEntrySet::UpdateGroupLength(bool SkipSequence, FileType type) { tk = g->first + "|0000"; // generate the element full tag if ( tagHT.count(tk) == 0) { // if element 0x0000 not found - gdcmDictEntry * tagZ = new gdcmDictEntry(gr_bid, 0x0000, "UL"); + gdcmDictEntry * tagZ = gdcmGlobal::GetDicts()->NewVirtualDictEntry(gr_bid, 0x0000, "UL"); elemZ = new gdcmHeaderEntry(tagZ); elemZ->SetLength(4); Add(elemZ); // create it -- 2.48.1