From 65467b71ee500909b0ef7c31d442ca0c160d6a15 Mon Sep 17 00:00:00 2001 From: regrain Date: Mon, 19 Jan 2004 16:32:32 +0000 Subject: [PATCH] * Add the update of header entries using the shadow library -- BeNours --- ChangeLog | 1 + gdcmPython/demo/PrintHeader.py | 2 +- src/gdcmDict.cxx | 8 +- src/gdcmDict.h | 8 +- src/gdcmDictSet.cxx | 8 +- src/gdcmDictSet.h | 4 +- src/gdcmHeader.h | 2 + src/gdcmHeaderEntry.h | 48 +++--- src/gdcmParser.cxx | 284 +++++++++++++++++++-------------- src/gdcmParser.h | 9 +- 10 files changed, 213 insertions(+), 161 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0eeb0871..39f5ba51 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,7 @@ 2004-01-19 Benoit Regrain * src/gdcmFile.cxx : bug fix concerning the close of file * src/gdcmParser.[h|cxx] : remove obvious Pub informations + * Add the update of header entries using the shadow library 2004-01-19 Benoit Regrain * removal of file gdcmHeader2.cxx diff --git a/gdcmPython/demo/PrintHeader.py b/gdcmPython/demo/PrintHeader.py index c5843d6f..7648b483 100644 --- a/gdcmPython/demo/PrintHeader.py +++ b/gdcmPython/demo/PrintHeader.py @@ -24,6 +24,6 @@ print "##############################################################" print "### Display all the elements and their respective values" print "## found in the ", FileName, " file." print "##############################################################" -ValDict = toRead.GetPubEntry() +ValDict = toRead.GetEntry() for key in ValDict.keys(): print "[%s] = [%s]" %(key, ValDict[key]) diff --git a/src/gdcmDict.cxx b/src/gdcmDict.cxx index 085de514..9f2d3882 100644 --- a/src/gdcmDict.cxx +++ b/src/gdcmDict.cxx @@ -211,7 +211,7 @@ bool gdcmDict::RemoveEntry (guint16 group, guint16 element) { * the name MAY CHANGE between two versions ! * @return the corresponding dictionnary entry when existing, NULL otherwise */ -gdcmDictEntry *gdcmDict::GetTagByName(TagName name) { +gdcmDictEntry *gdcmDict::GetDictEntryByName(TagName name) { if ( ! NameHt.count(name)) return NULL; return NameHt.find(name)->second; @@ -224,7 +224,7 @@ gdcmDictEntry *gdcmDict::GetTagByName(TagName name) { * @param element element of the entry to be found * @return the corresponding dictionnary entry when existing, NULL otherwise */ -gdcmDictEntry *gdcmDict::GetTagByNumber(guint16 group, guint16 element) { +gdcmDictEntry *gdcmDict::GetDictEntryByNumber(guint16 group, guint16 element) { TagKey key = gdcmDictEntry::TranslateToKey(group, element); if ( ! KeyHt.count(key)) return NULL; @@ -238,7 +238,7 @@ gdcmDictEntry *gdcmDict::GetTagByNumber(guint16 group, guint16 element) { * \sa gdcmDictSet::GetPubDictTagNamesByCategory * @return A list of all entries of the public dicom dictionnary. */ -std::list *gdcmDict::GetTagNames(void) +std::list *gdcmDict::GetDictEntryNames(void) { std::list *Result = new std::list; for (TagKeyHT::iterator tag = KeyHt.begin(); tag != KeyHt.end(); ++tag) @@ -272,7 +272,7 @@ std::list *gdcmDict::GetTagNames(void) * corresponding values are lists of all the dictionnary entries * among that group. */ -std::map > *gdcmDict::GetTagNamesByCategory(void) +std::map > *gdcmDict::GetDictEntryNamesByCategory(void) { std::map > *Result = new std::map >; diff --git a/src/gdcmDict.h b/src/gdcmDict.h index 8add2a6b..1e1f0754 100644 --- a/src/gdcmDict.h +++ b/src/gdcmDict.h @@ -42,12 +42,12 @@ public: bool RemoveEntry (guint16 group, guint16 element); // Tag - gdcmDictEntry * GetTagByName(TagName name); - gdcmDictEntry * GetTagByNumber(guint16 group, guint16 element); + gdcmDictEntry *GetDictEntryByName(TagName name); + gdcmDictEntry *GetDictEntryByNumber(guint16 group, guint16 element); - std::list *GetTagNames(void); + std::list *GetDictEntryNames(void); std::map > * - GetTagNamesByCategory(void); + GetDictEntryNamesByCategory(void); /** * \ingroup gdcmDict diff --git a/src/gdcmDictSet.cxx b/src/gdcmDictSet.cxx index 82962d6e..5982f00c 100644 --- a/src/gdcmDictSet.cxx +++ b/src/gdcmDictSet.cxx @@ -78,9 +78,9 @@ 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 *gdcmDictSet::GetPubDictEntryNames(void) { - return(GetDefaultPubDict()->GetTagNames()); + return(GetDefaultPubDict()->GetDictEntryNames()); } /** @@ -107,9 +107,9 @@ std::list *gdcmDictSet::GetPubDictTagNames(void) * corresponding values are lists of all the dictionnary entries * among that group. */ -std::map > *gdcmDictSet::GetPubDictTagNamesByCategory(void) +std::map > *gdcmDictSet::GetPubDictEntryNamesByCategory(void) { - return(GetDefaultPubDict()->GetTagNamesByCategory()); + return(GetDefaultPubDict()->GetDictEntryNamesByCategory()); } /** diff --git a/src/gdcmDictSet.h b/src/gdcmDictSet.h index 8ef38e95..a992fc66 100644 --- a/src/gdcmDictSet.h +++ b/src/gdcmDictSet.h @@ -33,9 +33,9 @@ public: void Print(std::ostream& os); - std::list *GetPubDictTagNames(void); + std::list *GetPubDictEntryNames(void); std::map > * - GetPubDictTagNamesByCategory(void); + GetPubDictEntryNamesByCategory(void); void LoadDictFromFile(std::string FileName, DictKey Name); diff --git a/src/gdcmHeader.h b/src/gdcmHeader.h index 1ddff5a0..c07c94d2 100644 --- a/src/gdcmHeader.h +++ b/src/gdcmHeader.h @@ -93,6 +93,8 @@ public: inline virtual bool SetEntryByNumber(std::string content,guint16 group, guint16 element) { return(gdcmParser::SetEntryByNumber(content,group,element)); } + inline virtual void UpdateShaEntries(void) + { gdcmParser::UpdateShaEntries(); } // Read (used in gdcmFile) void SetImageDataSize(size_t ExpectedSize); diff --git a/src/gdcmHeaderEntry.h b/src/gdcmHeaderEntry.h index f414704c..01f2bc74 100644 --- a/src/gdcmHeaderEntry.h +++ b/src/gdcmHeaderEntry.h @@ -24,9 +24,11 @@ public: inline std::string GetName(void) { return entry->GetName(); }; inline std::string GetVR(void) { return entry->GetVR(); }; inline std::string GetValue(void) { return value; }; + inline void * GetVoidArea(void) { return voidArea; }; inline size_t GetOffset(void) { return Offset; }; inline guint32 GetLength(void) { return UsableLength; }; + inline void SetVR(std::string v) { entry->SetVR(v); }; inline void SetLength(guint32 l) { ReadLength=UsableLength=l;}; @@ -38,14 +40,6 @@ public: inline void SetValue(std::string val) { value = val; }; inline void SetVoidArea(void * area) { voidArea = area; }; - void Print (std::ostream & os = std::cout); - /** - * \ingroup gdcmHeaderEntry - * \brief Sets the print level for the Dicom Header Elements - * \note 0 for Light Print; 1 for 'medium' Print, 2 for Heavy - */ - void SetPrintLevel(int level) { printLevel = level; }; - /** * \ingroup gdcmHeaderEntry * \brief Sets the offset of the Dicom Element @@ -54,15 +48,6 @@ public: */ inline void gdcmHeaderEntry::SetOffset(size_t of) { Offset = of; }; - /** - * \ingroup gdcmHeaderEntry - * \brief Sets the DicEntry of the current Dicom Element - * @param NewEntry pointer to the DictEntry - */ - inline void gdcmHeaderEntry::SetDictEntry(gdcmDictEntry *NewEntry) { - entry = NewEntry; - }; - /** * \ingroup gdcmHeaderEntry * \brief Sets to TRUE the ImplicitVr flag of the current Dicom Element @@ -80,6 +65,24 @@ public: return ImplicitVr; }; + /** + * \ingroup gdcmHeaderEntry + * \brief tells us if the VR of the current Dicom Element is Unkonwn + * @return true if the VR is unkonwn + */ + inline bool gdcmHeaderEntry::IsVRUnknown(void) { + return entry->IsVRUnknown(); + }; + + /** + * \ingroup gdcmHeaderEntry + * \brief Sets the DicEntry of the current Dicom Element + * @param NewEntry pointer to the DictEntry + */ + inline void gdcmHeaderEntry::SetDictEntry(gdcmDictEntry *NewEntry) { + entry = NewEntry; + }; + /** * \ingroup gdcmHeaderEntry * \brief Gets the DicEntry of the current Dicom Element @@ -91,12 +94,11 @@ public: /** * \ingroup gdcmHeaderEntry - * \brief tells us if the VR of the current Dicom Element is Unkonwn - * @return true if the VR is unkonwn - */ - inline bool gdcmHeaderEntry::IsVRUnknown(void) { - return entry->IsVRUnknown(); - }; + * \brief Sets the print level for the Dicom Header Elements + * \note 0 for Light Print; 1 for 'medium' Print, 2 for Heavy + */ + void SetPrintLevel(int level) { printLevel = level; }; + void Print (std::ostream & os = std::cout); private: // FIXME: In fact we should be more specific and use : diff --git a/src/gdcmParser.cxx b/src/gdcmParser.cxx index a1ce1407..ec1dcb9f 100644 --- a/src/gdcmParser.cxx +++ b/src/gdcmParser.cxx @@ -497,7 +497,7 @@ int gdcmParser::CheckIfEntryExistByNumber(guint16 group, guint16 element ) */ std::string gdcmParser::GetEntryByName(std::string tagName) { - gdcmDictEntry *dictEntry = RefPubDict->GetTagByName(tagName); + gdcmDictEntry *dictEntry = RefPubDict->GetDictEntryByName(tagName); if( dictEntry == NULL) return GDCM_UNFOUND; @@ -520,7 +520,7 @@ std::string gdcmParser::GetEntryByName(std::string tagName) */ std::string gdcmParser::GetEntryVRByName(std::string tagName) { - gdcmDictEntry *dictEntry = RefPubDict->GetTagByName(tagName); + gdcmDictEntry *dictEntry = RefPubDict->GetDictEntryByName(tagName); if( dictEntry == NULL) return GDCM_UNFOUND; @@ -579,7 +579,7 @@ std::string gdcmParser::GetEntryVRByNumber(guint16 group, guint16 element) */ bool gdcmParser::SetEntryByName(std::string content,std::string tagName) { - gdcmDictEntry *dictEntry = RefPubDict->GetTagByName(tagName); + gdcmDictEntry *dictEntry = RefPubDict->GetDictEntryByName(tagName); if( dictEntry == NULL) return false; @@ -649,13 +649,13 @@ bool gdcmParser::SetEntryByNumber(std::string content, * the given value. * \warning Use with extreme caution. * @param length new length to substitute with - * @param group group of the ElVal to modify - * @param element element of the ElVal to modify + * @param group group of the entry to modify + * @param element element of the Entry to modify * @return 1 on success, 0 otherwise. */ bool gdcmParser::SetEntryLengthByNumber(guint32 length, - guint16 group, guint16 element) + guint16 group, guint16 element) { TagKey key = gdcmDictEntry::TranslateToKey(group, element); if ( ! tagHT.count(key)) @@ -753,6 +753,38 @@ bool gdcmParser::SetEntryVoidAreaByNumber(void * area,guint16 group, guint16 ele return true; } +/** + * \ingroup gdcmParser + * \brief Update the entries with the shadow dictionary. Only odd entries are + * analized + */ +void gdcmParser::UpdateShaEntries(void) +{ + if(!RefShaDict) + return; + + gdcmDictEntry *entry; + std::string vr; + + for(ListTag::iterator it=listEntries.begin(); + it!=listEntries.end(); + ++it) + { + // Odd group => from public dictionary + if((*it)->GetGroup()%1==0) + continue; + + // Peer group => search the corresponding dict entry + entry=RefShaDict->GetDictEntryByNumber((*it)->GetGroup(),(*it)->GetElement()); + if(entry) + { + (*it)->SetDictEntry(entry); + vr=(*it)->GetVR(); + CheckHeaderEntryVR(*it,vr); + } + } +} + /** * \ingroup gdcmParser * \brief Searches within the Header Entries for a Dicom Element of @@ -763,7 +795,7 @@ bool gdcmParser::SetEntryVoidAreaByNumber(void * area,guint16 group, guint16 ele */ gdcmHeaderEntry *gdcmParser::GetHeaderEntryByName(std::string tagName) { - gdcmDictEntry *dictEntry = RefPubDict->GetTagByName(tagName); + gdcmDictEntry *dictEntry = RefPubDict->GetDictEntryByName(tagName); if( dictEntry == NULL) return NULL; @@ -1141,17 +1173,17 @@ void gdcmParser::LoadHeaderEntries(void) * \brief Loads the element content if it's length is not bigger * than the value specified with * gdcmParser::SetMaxSizeLoadEntry() - * @param ElVal Header Entry (Dicom Element) to be dealt with + * @param Entry Header Entry (Dicom Element) to be dealt with */ -void gdcmParser::LoadHeaderEntry(gdcmHeaderEntry * ElVal) +void gdcmParser::LoadHeaderEntry(gdcmHeaderEntry *Entry) { size_t item_read; - guint16 group = ElVal->GetGroup(); - std::string vr= ElVal->GetVR(); - guint32 length = ElVal->GetLength(); + guint16 group = Entry->GetGroup(); + std::string vr= Entry->GetVR(); + guint32 length = Entry->GetLength(); bool SkipLoad = false; - fseek(fp, (long)ElVal->GetOffset(), SEEK_SET); + fseek(fp, (long)Entry->GetOffset(), SEEK_SET); // the test was commented out to 'go inside' the SeQuences // we don't any longer skip them ! @@ -1168,15 +1200,15 @@ void gdcmParser::LoadHeaderEntry(gdcmHeaderEntry * ElVal) if ( SkipLoad ) { - ElVal->SetLength(0); - ElVal->SetValue("gdcm::Skipped"); + Entry->SetLength(0); + Entry->SetValue("gdcm::Skipped"); return; } // When the length is zero things are easy: if ( length == 0 ) { - ElVal->SetValue(""); + Entry->SetValue(""); return; } @@ -1187,10 +1219,10 @@ void gdcmParser::LoadHeaderEntry(gdcmHeaderEntry * ElVal) { std::ostringstream s; s << "gdcm::NotLoaded."; - s << " Address:" << (long)ElVal->GetOffset(); - s << " Length:" << ElVal->GetLength(); - s << " x(" << std::hex << ElVal->GetLength() << ")"; - ElVal->SetValue(s.str()); + s << " Address:" << (long)Entry->GetOffset(); + s << " Length:" << Entry->GetLength(); + s << " x(" << std::hex << Entry->GetLength() << ")"; + Entry->SetValue(s.str()); return; } @@ -1201,7 +1233,7 @@ void gdcmParser::LoadHeaderEntry(gdcmHeaderEntry * ElVal) // contain a set of integers (not a single one) // Any compacter code suggested (?) - if ( IsHeaderEntryAnInteger(ElVal) ) + if ( IsHeaderEntryAnInteger(Entry) ) { guint32 NewInt; std::ostringstream s; @@ -1240,7 +1272,7 @@ void gdcmParser::LoadHeaderEntry(gdcmHeaderEntry * ElVal) #ifdef GDCM_NO_ANSI_STRING_STREAM s << std::ends; // to avoid oddities on Solaris #endif //GDCM_NO_ANSI_STRING_STREAM - ElVal->SetValue(s.str()); + Entry->SetValue(s.str()); return; } @@ -1258,10 +1290,10 @@ void gdcmParser::LoadHeaderEntry(gdcmHeaderEntry * ElVal) { free(NewValue); dbg.Verbose(1, "gdcmParser::LoadElementValue","unread element value"); - ElVal->SetValue("gdcm::UnRead"); + Entry->SetValue("gdcm::UnRead"); return; } - ElVal->SetValue(NewValue); + Entry->SetValue(NewValue); free(NewValue); } @@ -1284,15 +1316,15 @@ void gdcmParser::AddHeaderEntry(gdcmHeaderEntry * newHeaderEntry) /** * \ingroup gdcmParser * \brief - * @param ElVal : Header Entry whose length of the value shall be loaded. + * @param Entry Header Entry whose length of the value shall be loaded. * @return */ - void gdcmParser::FindHeaderEntryLength (gdcmHeaderEntry * ElVal) + void gdcmParser::FindHeaderEntryLength (gdcmHeaderEntry * Entry) { - guint16 element = ElVal->GetElement(); - guint16 group = ElVal->GetGroup(); - std::string vr = ElVal->GetVR(); + guint16 element = Entry->GetElement(); + guint16 group = Entry->GetGroup(); + std::string vr = Entry->GetVR(); guint16 length16; if( (element == 0x0010) && (group == 0x7fe0) ) { @@ -1301,7 +1333,7 @@ void gdcmParser::AddHeaderEntry(gdcmHeaderEntry * newHeaderEntry) "we reached 7fe0 0010"); } - if ( (filetype == ExplicitVR) && ! ElVal->IsImplicitVr() ) + if ( (filetype == ExplicitVR) && ! Entry->IsImplicitVr() ) { if ( (vr=="OB") || (vr=="OW") || (vr=="SQ") || (vr=="UN") ) { @@ -1313,10 +1345,10 @@ void gdcmParser::AddHeaderEntry(gdcmHeaderEntry * newHeaderEntry) if ( (vr == "OB") && (length32 == 0xffffffff) ) { - ElVal->SetLength(FindHeaderEntryLengthOB()); + Entry->SetLength(FindHeaderEntryLengthOB()); return; } - FixHeaderEntryFoundLength(ElVal, length32); + FixHeaderEntryFoundLength(Entry, length32); return; } @@ -1362,8 +1394,8 @@ void gdcmParser::AddHeaderEntry(gdcmHeaderEntry * newHeaderEntry) SwitchSwapToBigEndian(); // Restore the unproperly loaded values i.e. the group, the element // and the dictionary entry depending on them. - guint16 CorrectGroup = SwapShort(ElVal->GetGroup()); - guint16 CorrectElem = SwapShort(ElVal->GetElement()); + guint16 CorrectGroup = SwapShort(Entry->GetGroup()); + guint16 CorrectElem = SwapShort(Entry->GetElement()); gdcmDictEntry * NewTag = GetDictEntryByNumber(CorrectGroup, CorrectElem); if (!NewTag) @@ -1373,7 +1405,7 @@ void gdcmParser::AddHeaderEntry(gdcmHeaderEntry * newHeaderEntry) } // FIXME this can create a memory leaks on the old entry that be // left unreferenced. - ElVal->SetDictEntry(NewTag); + Entry->SetDictEntry(NewTag); } // Heuristic: well some files are really ill-formed. @@ -1386,7 +1418,7 @@ void gdcmParser::AddHeaderEntry(gdcmHeaderEntry * newHeaderEntry) // Unknown Sequence Length } - FixHeaderEntryFoundLength(ElVal, (guint32)length16); + FixHeaderEntryFoundLength(Entry, (guint32)length16); return; } @@ -1396,24 +1428,22 @@ void gdcmParser::AddHeaderEntry(gdcmHeaderEntry * newHeaderEntry) // on Data elements "Implicit and Explicit VR Data Elements shall // not coexist in a Data Set and Data Sets nested within it".] // Length is on 4 bytes. - FixHeaderEntryFoundLength(ElVal, ReadInt32()); + FixHeaderEntryFoundLength(Entry, ReadInt32()); return; } /** * \ingroup gdcmParser * \brief Find the Value Representation of the current Dicom Element. - * @param ElVal + * @param Entry */ -void gdcmParser::FindHeaderEntryVR( gdcmHeaderEntry *ElVal) +void gdcmParser::FindHeaderEntryVR( gdcmHeaderEntry *Entry) { if (filetype != ExplicitVR) return; char VR[3]; - std::string vr; int lgrLue; - char msg[100]; // for sprintf. Sorry long PositionOnEntry = ftell(fp); // Warning: we believe this is explicit VR (Value Representation) because @@ -1423,12 +1453,38 @@ void gdcmParser::FindHeaderEntryVR( gdcmHeaderEntry *ElVal) // within an explicit VR file. Hence we make sure the present tag // is in explicit VR and try to fix things if it happens not to be // the case. - bool RealExplicit = true; lgrLue=fread (&VR, (size_t)2,(size_t)1, fp); VR[2]=0; - vr = std::string(VR); - + if(!CheckHeaderEntryVR(Entry,VR)) + { + fseek(fp, PositionOnEntry, SEEK_SET); + // When this element is known in the dictionary we shall use, e.g. for + // the semantics (see the usage of IsAnInteger), the VR proposed by the + // dictionary entry. Still we have to flag the element as implicit since + // we know now our assumption on expliciteness is not furfilled. + // avoid . + if ( Entry->IsVRUnknown() ) + Entry->SetVR("Implicit"); + Entry->SetImplicitVr(); + } +} + +/** + * \ingroup gdcmParser + * \brief 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. + * @param Entry + * @param VR + * @return false if the VR is incorrect of if the VR isn't referenced + * otherwise, it returns true +*/ +bool gdcmParser::CheckHeaderEntryVR (gdcmHeaderEntry *Entry, VRKey vr) +{ + char msg[100]; // for sprintf + bool RealExplicit = true; + // Assume we are reading a falsely explicit VR file i.e. we reached // a tag where we expect reading a VR but are in fact we read the // first to bytes of the length. Then we will interogate (through find) @@ -1437,7 +1493,7 @@ void gdcmParser::FindHeaderEntryVR( gdcmHeaderEntry *ElVal) // expected VR read happens to be non-ascii characters we consider // we hit falsely explicit VR tag. - if ( (!isalpha(VR[0])) && (!isalpha(VR[1])) ) + if ( (!isalpha(vr[0])) && (!isalpha(vr[1])) ) RealExplicit = false; // CLEANME searching the dicom_vr at each occurence is expensive. @@ -1446,49 +1502,37 @@ void gdcmParser::FindHeaderEntryVR( gdcmHeaderEntry *ElVal) if ( RealExplicit && !gdcmGlobal::GetVR()->Count(vr) ) RealExplicit= false; - if ( RealExplicit ) + if ( !RealExplicit ) + { + // We thought this was explicit VR, but we end up with an + // implicit VR tag. Let's backtrack. + sprintf(msg,"Falsely explicit vr file (%04x,%04x)\n", + Entry->GetGroup(),Entry->GetElement()); + dbg.Verbose(1, "gdcmParser::FindVR: ",msg); + + return(false); + } + + if ( Entry->IsVRUnknown() ) + { + // When not a dictionary entry, we can safely overwrite the VR. + Entry->SetVR(vr); + } + else if ( Entry->GetVR() != vr ) { - if ( ElVal->IsVRUnknown() ) - { - // When not a dictionary entry, we can safely overwrite the VR. - ElVal->SetVR(vr); - return; - } - if ( ElVal->GetVR() == vr ) - { - // The VR we just read and the dictionary agree. Nothing to do. - return; - } // The VR present in the file and the dictionary disagree. We assume // the file writer knew best and use the VR of the file. Since it would // 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 = NewVirtualDictEntry(ElVal->GetGroup(), - ElVal->GetElement(), + gdcmDictEntry* NewTag = NewVirtualDictEntry(Entry->GetGroup(), + Entry->GetElement(), vr, "FIXME", - ElVal->GetName()); - ElVal->SetDictEntry(NewTag); - return; + Entry->GetName()); + Entry->SetDictEntry(NewTag); } - - // We thought this was explicit VR, but we end up with an - // implicit VR tag. Let's backtrack. - - sprintf(msg,"Falsely explicit vr file (%04x,%04x)\n", - ElVal->GetGroup(),ElVal->GetElement()); - dbg.Verbose(1, "gdcmParser::FindVR: ",msg); - - fseek(fp, PositionOnEntry, SEEK_SET); - // When this element is known in the dictionary we shall use, e.g. for - // the semantics (see the usage of IsAnInteger), the VR proposed by the - // dictionary entry. Still we have to flag the element as implicit since - // we know now our assumption on expliciteness is not furfilled. - // avoid . - if ( ElVal->IsVRUnknown() ) - ElVal->SetVR("Implicit"); - ElVal->SetImplicitVr(); + return(true); } /** @@ -1498,7 +1542,7 @@ void gdcmParser::FindHeaderEntryVR( gdcmHeaderEntry *ElVal) * @param entry * @return */ -void gdcmParser::SkipHeaderEntry(gdcmHeaderEntry * entry) +void gdcmParser::SkipHeaderEntry(gdcmHeaderEntry *entry) { SkipBytes(entry->GetLength()); } @@ -1509,9 +1553,9 @@ void gdcmParser::SkipHeaderEntry(gdcmHeaderEntry * entry) * the parser went Jabberwocky) one can hope improving things by * applying this heuristic. */ -void gdcmParser::FixHeaderEntryFoundLength(gdcmHeaderEntry * ElVal, guint32 FoundLength) +void gdcmParser::FixHeaderEntryFoundLength(gdcmHeaderEntry *Entry, guint32 FoundLength) { - ElVal->SetReadLength(FoundLength); // will be updated only if a bug is found + Entry->SetReadLength(FoundLength); // will be updated only if a bug is found if ( FoundLength == 0xffffffff) { @@ -1524,26 +1568,26 @@ void gdcmParser::FixHeaderEntryFoundLength(gdcmHeaderEntry * ElVal, guint32 Foun { // The following 'if' will be removed when there is no more // images on Creatis HDs with a 13 length for Manufacturer... - if ( (ElVal->GetGroup() != 0x0008) || - ( (ElVal->GetElement() != 0x0070) && (ElVal->GetElement() != 0x0080) ) ) { + if ( (Entry->GetGroup() != 0x0008) || + ( (Entry->GetElement() != 0x0070) && (Entry->GetElement() != 0x0080) ) ) { // end of remove area FoundLength =10; - ElVal->SetReadLength(10); // a bug is to be fixed + Entry->SetReadLength(10); // a bug is to be fixed } } // to fix some garbage 'Leonardo' Siemens images // May be commented out to avoid overhead - else if ( (ElVal->GetGroup() == 0x0009) && - ( (ElVal->GetElement() == 0x1113) || (ElVal->GetElement() == 0x1114) ) ) + else if ( (Entry->GetGroup() == 0x0009) && + ( (Entry->GetElement() == 0x1113) || (Entry->GetElement() == 0x1114) ) ) { FoundLength =4; - ElVal->SetReadLength(4); // a bug is to be fixed + Entry->SetReadLength(4); // a bug is to be fixed } // end of fix // to try to 'go inside' SeQuences (with length), and not to skip them - else if ( ElVal->GetVR() == "SQ") + else if ( Entry->GetVR() == "SQ") { if (enableSequences) // only if the user does want to ! FoundLength =0; @@ -1558,7 +1602,7 @@ void gdcmParser::FixHeaderEntryFoundLength(gdcmHeaderEntry * ElVal, guint32 Foun // if we set the length to zero IsHeaderEntryAnInteger() breaks... // if we don't, we lost 28800 characters from the Header :-( - else if(ElVal->GetGroup() == 0xfffe) + else if(Entry->GetGroup() == 0xfffe) { // sometimes, length seems to be wrong FoundLength =0; // some more clever checking to be done ! @@ -1567,22 +1611,22 @@ void gdcmParser::FixHeaderEntryFoundLength(gdcmHeaderEntry * ElVal, guint32 Foun // causes troubles :-( } - ElVal->SetUsableLength(FoundLength); + Entry->SetUsableLength(FoundLength); } /** * \ingroup gdcmParser * \brief Apply some heuristics to predict wether the considered * element value contains/represents an integer or not. - * @param ElVal The element value on which to apply the predicate. + * @param Entry The element value on which to apply the predicate. * @return The result of the heuristical predicate. */ -bool gdcmParser::IsHeaderEntryAnInteger(gdcmHeaderEntry * ElVal) +bool gdcmParser::IsHeaderEntryAnInteger(gdcmHeaderEntry *Entry) { - guint16 element = ElVal->GetElement(); - guint16 group = ElVal->GetGroup(); - std::string vr = ElVal->GetVR(); - guint32 length = ElVal->GetLength(); + guint16 element = Entry->GetElement(); + guint16 group = Entry->GetGroup(); + std::string vr = Entry->GetVR(); + guint32 length = Entry->GetLength(); // When we have some semantics on the element we just read, and if we // a priori know we are dealing with an integer, then we shall be @@ -1972,13 +2016,13 @@ gdcmDictEntry *gdcmParser::GetDictEntryByName(std::string Name) } if (RefPubDict) { - found = RefPubDict->GetTagByName(Name); + found = RefPubDict->GetDictEntryByName(Name); if (found) return found; } if (RefShaDict) { - found = RefShaDict->GetTagByName(Name); + found = RefShaDict->GetDictEntryByName(Name); if (found) return found; } @@ -2005,13 +2049,13 @@ gdcmDictEntry *gdcmParser::GetDictEntryByNumber(guint16 group,guint16 element) } if (RefPubDict) { - found = RefPubDict->GetTagByNumber(group, element); + found = RefPubDict->GetDictEntryByNumber(group, element); if (found) return found; } if (RefShaDict) { - found = RefShaDict->GetTagByNumber(group, element); + found = RefShaDict->GetDictEntryByNumber(group, element); if (found) return found; } @@ -2026,7 +2070,7 @@ gdcmDictEntry *gdcmParser::GetDictEntryByNumber(guint16 group,guint16 element) gdcmHeaderEntry *gdcmParser::ReadNextHeaderEntry(void) { guint16 g,n; - gdcmHeaderEntry *NewElVal; + gdcmHeaderEntry *NewEntry; g = ReadInt16(); n = ReadInt16(); @@ -2036,18 +2080,18 @@ gdcmHeaderEntry *gdcmParser::ReadNextHeaderEntry(void) // has to be considered as finished. return (gdcmHeaderEntry *)0; - NewElVal = NewHeaderEntryByNumber(g, n); - FindHeaderEntryVR(NewElVal); - FindHeaderEntryLength(NewElVal); + NewEntry = NewHeaderEntryByNumber(g, n); + FindHeaderEntryVR(NewEntry); + FindHeaderEntryLength(NewEntry); if (errno == 1) { // Call it quits return NULL; } - NewElVal->SetOffset(ftell(fp)); + NewEntry->SetOffset(ftell(fp)); //if ( (g==0x7fe0) && (n==0x0010) ) - return NewElVal; + return NewEntry; } /** @@ -2063,14 +2107,14 @@ gdcmHeaderEntry *gdcmParser::NewHeaderEntryByName(std::string Name) if (!NewTag) NewTag = NewVirtualDictEntry(0xffff, 0xffff, "LO", "Unknown", Name); - gdcmHeaderEntry* NewElVal = new gdcmHeaderEntry(NewTag); - if (!NewElVal) + gdcmHeaderEntry* NewEntry = new gdcmHeaderEntry(NewTag); + if (!NewEntry) { dbg.Verbose(1, "gdcmParser::ObtainHeaderEntryByName", "failed to allocate gdcmHeaderEntry"); return (gdcmHeaderEntry *)0; } - return NewElVal; + return NewEntry; } /** @@ -2105,14 +2149,14 @@ gdcmHeaderEntry *gdcmParser::NewHeaderEntryByNumber(guint16 Group, guint16 Elem) if (!NewTag) NewTag = NewVirtualDictEntry(Group, Elem); - gdcmHeaderEntry* NewElVal = new gdcmHeaderEntry(NewTag); - if (!NewElVal) + gdcmHeaderEntry* NewEntry = new gdcmHeaderEntry(NewTag); + if (!NewEntry) { dbg.Verbose(1, "gdcmParser::NewHeaderEntryByNumber", "failed to allocate gdcmHeaderEntry"); return NULL; } - return NewElVal; + return NewEntry; } /** @@ -2128,24 +2172,24 @@ gdcmHeaderEntry *gdcmParser::NewHeaderEntryByNumber(guint16 Group, guint16 Elem) gdcmHeaderEntry *gdcmParser::NewManualHeaderEntryToPubDict(std::string NewTagName, std::string VR) { - gdcmHeaderEntry *NewElVal = (gdcmHeaderEntry *)0; + gdcmHeaderEntry *NewEntry = NULL; guint32 StuffGroup = 0xffff; // Group to be stuffed with additional info guint32 FreeElem = 0; - gdcmDictEntry *NewEntry = (gdcmDictEntry *)0; + gdcmDictEntry *DictEntry = NULL; FreeElem = GenerateFreeTagKeyInGroup(StuffGroup); if (FreeElem == UINT32_MAX) { - dbg.Verbose(1, "gdcmHeader::NewManualElValToPubDict", + dbg.Verbose(1, "gdcmHeader::NewManualHeaderEntryToPubDict", "Group 0xffff in Public Dict is full"); return NULL; } - NewEntry = NewVirtualDictEntry(StuffGroup, FreeElem, + DictEntry = NewVirtualDictEntry(StuffGroup, FreeElem, VR, "GDCM", NewTagName); - NewElVal = new gdcmHeaderEntry(NewEntry); - AddHeaderEntry(NewElVal); - return NewElVal; + NewEntry = new gdcmHeaderEntry(DictEntry); + AddHeaderEntry(NewEntry); + return NewEntry; } /** diff --git a/src/gdcmParser.h b/src/gdcmParser.h index 0984aa07..54c6636c 100644 --- a/src/gdcmParser.h +++ b/src/gdcmParser.h @@ -18,11 +18,11 @@ typedef std::string VRKey; typedef std::string VRAtr; typedef std::map VRHT; // Value Representation Hash Table -typedef std::multimap TagHeaderEntryHT; -typedef std::pair PairHT; +typedef std::multimap TagHeaderEntryHT; +typedef std::pair PairHT; typedef std::pair IterHT; -typedef std::list ListTag; // for linking together the Elements +typedef std::list ListTag; // for linking together the Elements typedef std::string GroupKey; typedef std::map GroupHT; @@ -117,6 +117,8 @@ protected: virtual void *LoadEntryVoidArea (guint16 Group, guint16 Element); virtual bool SetEntryVoidAreaByNumber(void *a, guint16 Group, guint16 Elem); + virtual void UpdateShaEntries(void); + // Header entry gdcmHeaderEntry *GetHeaderEntryByName (std::string Name); gdcmHeaderEntry *GetHeaderEntryByNumber(guint16 group, guint16 element); @@ -142,6 +144,7 @@ private: void AddHeaderEntry (gdcmHeaderEntry *); void FindHeaderEntryLength(gdcmHeaderEntry *); void FindHeaderEntryVR (gdcmHeaderEntry *); + bool CheckHeaderEntryVR (gdcmHeaderEntry *, VRKey); void SkipHeaderEntry (gdcmHeaderEntry *); void FixHeaderEntryFoundLength(gdcmHeaderEntry *, guint32); -- 2.48.1