From: jpr Date: Mon, 10 Nov 2003 14:17:12 +0000 (+0000) Subject: *FIX : gdcmHeader::LoadElements is now based X-Git-Tag: Version0.3.1~42 X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=commitdiff_plain;ds=inline;h=ea14e11cdd726f9c7e6d6384c7e9e508bc6efc2d;p=gdcm.git *FIX : gdcmHeader::LoadElements is now based on the ListTag listElem member, not longer on the TagElValueHT tagHt member *ENH : PrintPubElVal shows (temporarily) both results, with the tagHt member and the listElem member. (it's easier to 'see' the problems when using Printheader) *FIX : old private member LgrElem is now splitted into ReadLength : Length actually found on disk (updated only if bug fixing is necessary), for internal use only UsableLength : Updated by FixFoundLength, to fix a bug or to allow Parser going on. Will allow to re-write a kosher header when a SeQuence with a length (not 0000) is found Warning : gdcmFile::Write still uses the TagHt (not ListElem) because gdcmElValSet::Add does not update ListElem (to be written) --- diff --git a/src/gdcmElValSet.cxx b/src/gdcmElValSet.cxx index d9e8c39d..7678bddb 100644 --- a/src/gdcmElValSet.cxx +++ b/src/gdcmElValSet.cxx @@ -68,6 +68,8 @@ void gdcmElValSet::Print(std::ostream & os) { std::string d2; gdcmTS * ts = gdcmGlobal::GetTS(); + std::cout << "------------- using tagHt ----------------------------" << std::endl; + for (TagElValueHT::iterator tag = tagHt.begin(); tag != tagHt.end(); ++tag){ @@ -98,7 +100,7 @@ void gdcmElValSet::Print(std::ostream & os) { os << std::endl; } - std::cout << "----------------------------------------------" << std::endl; + std::cout << "------------ using listElem -----------------" << std::endl; //for (ListTag::iterator i = listElem.begin(); @@ -115,7 +117,7 @@ void gdcmElValSet::Print(std::ostream & os) { d2 = _CreateCleanString(v); // replace non printable characters by '.' //os << std::hex <GetLength(); + os << " lgr : " << (*i)->GetReadLength(); os << ", Offset : " << o; os << " x(" << std::hex << o << std::dec << ") "; os << "\t[" << (*i)->GetVR() << "]"; @@ -133,9 +135,7 @@ void gdcmElValSet::Print(std::ostream & os) { } } os << std::endl; - - } - + } } /** @@ -233,9 +233,6 @@ int gdcmElValSet::SetElValueByNumber(std::string content, else lgr = l; tagHt[key]->SetLength(lgr); - - - return 1; } @@ -435,9 +432,14 @@ void gdcmElValSet::UpdateGroupLength(bool SkipSequence, FileType type) { /** * \ingroup gdcmElValSet - * \brief - * @param type - * @param _fp + * \brief writes on disc according to the requested format + * \ (ACR-NEMA, DICOM, RAW) the image + * \ warning does NOT add the missing elements in the header : + * \ it's up to the user doing it ! + * \ (function CheckHeaderCoherence to be written) + * @param type type of the File to be written + * (ACR-NEMA, DICOM, RAW) + * @param _fp already open file pointer * @return */ void gdcmElValSet::WriteElements(FileType type, FILE * _fp) { @@ -449,6 +451,10 @@ void gdcmElValSet::WriteElements(FileType type, FILE * _fp) { guint16 val_uint16; std::vector tokens; + + // TODO : use listElem to iterate, not TagHt! + // pb : gdcmElValSet.Add does NOT update listElem + // find a trick in STL to do it, at low cost ! void *ptr; diff --git a/src/gdcmElValue.h b/src/gdcmElValue.h index 0d91c3d7..400a03b8 100644 --- a/src/gdcmElValue.h +++ b/src/gdcmElValue.h @@ -1,4 +1,4 @@ -// $Header: /cvs/public/gdcm/src/Attic/gdcmElValue.h,v 1.8 2003/10/09 13:22:54 jpr Exp $ +// $Header: /cvs/public/gdcm/src/Attic/gdcmElValue.h,v 1.9 2003/11/10 14:17:12 jpr Exp $ #ifndef GDCMELVALUE_H #define GDCMELVALUE_H @@ -14,11 +14,23 @@ class gdcmHeader; class GDCM_EXPORT gdcmElValue { private: gdcmDictEntry *entry; - guint32 LgrElem; + guint32 UsableLength; // Updated from ReadLength, by FixFoungLentgh() + // for fixing a bug in the header or helping + // the parser going on + + guint32 ReadLength; // Length actually read on disk + // (before FixFoundLength) + // ReadLength will be updated only when + // FixFoundLength actually fixes a bug in the header, + // not when it performs a trick to help the Parser + // going on. + // *for internal* use only + bool ImplicitVr; // Even when reading explicit vr files, some // elements happen to be implicit. Flag them here // since we can't use the entry->vr without breaking // the underlying dictionary. + void SetOffset(size_t of){ Offset = of; }; // FIXME: In fact we should be more specific and use : //friend gdcmElValue * gdcmHeader::ReadNextElement(void); @@ -37,21 +49,27 @@ public: gdcmDictEntry * GetDictEntry(void) { return entry; }; - guint16 GetGroup(void) { return entry->GetGroup(); }; - guint16 GetElement(void) { return entry->GetElement();}; - std::string GetKey(void) { return entry->GetKey(); }; - std::string GetName(void) { return entry->GetName(); }; - std::string GetVR(void) { return entry->GetVR(); }; - std::string GetValue(void) { return value; }; - void * GetVoidArea(void) { return voidArea; }; - size_t GetOffset(void) { return Offset; }; - guint32 GetLength(void) { return LgrElem; }; + guint16 GetGroup(void) { return entry->GetGroup(); }; + guint16 GetElement(void) { return entry->GetElement();}; + std::string GetKey(void) { return entry->GetKey(); }; + std::string GetName(void) { return entry->GetName(); }; + std::string GetVR(void) { return entry->GetVR(); }; + std::string GetValue(void) { return value; }; + void * GetVoidArea(void) { return voidArea; }; + size_t GetOffset(void) { return Offset; }; + guint32 GetLength(void) { return UsableLength; }; + // for internal use only! + guint32 GetReadLength(void){ return ReadLength; }; - void SetVR(std::string v) { entry->SetVR(v); }; - void SetLength(guint32 l) { LgrElem = l; }; - void SetValue(std::string val){ value = val; }; - void SetVoidArea(void * area) { voidArea = area; }; - + void SetVR(std::string v) { entry->SetVR(v); }; + void SetLength(guint32 l) { ReadLength=UsableLength=l;}; + // The following 2 members, for internal use only ! + void SetReadLength(guint32 l) { ReadLength = l; }; + void SetUsableLength(guint32 l){ UsableLength = l; }; + + void SetValue(std::string val) { value = val; }; + void SetVoidArea(void * area) { voidArea = area; }; + }; #endif diff --git a/src/gdcmHeader.cxx b/src/gdcmHeader.cxx index 9cdc5beb..79ad3c0b 100644 --- a/src/gdcmHeader.cxx +++ b/src/gdcmHeader.cxx @@ -1,4 +1,4 @@ -// $Header: /cvs/public/gdcm/src/Attic/gdcmHeader.cxx,v 1.112 2003/11/10 09:21:40 jpr Exp $ +// $Header: /cvs/public/gdcm/src/Attic/gdcmHeader.cxx,v 1.113 2003/11/10 14:17:12 jpr Exp $ #include "gdcmHeader.h" @@ -627,6 +627,9 @@ bool gdcmHeader::IsDicomV3(void) { * applying this heuristic. */ void gdcmHeader::FixFoundLength(gdcmElValue * ElVal, guint32 FoundLength) { + + ElVal->SetReadLength(FoundLength); // will be updated only if a bug is found + if ( FoundLength == 0xffffffff) FoundLength = 0; @@ -635,9 +638,11 @@ void gdcmHeader::FixFoundLength(gdcmElValue * ElVal, guint32 FoundLength) { else if (FoundLength == 13) { // 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)) { + if ( (ElVal->GetGroup() != 0x0008) && + ( (ElVal->GetElement() != 0x0070) || (ElVal->GetElement() != 0x0080) ) ) { // end of remove area FoundLength =10; + ElVal->SetReadLength(10); // a bug is to be fixed } } // to fix some garbage 'Leonardo' Siemens images @@ -645,7 +650,8 @@ void gdcmHeader::FixFoundLength(gdcmElValue * ElVal, guint32 FoundLength) { else if ( (ElVal->GetGroup() == 0x0009) && ( (ElVal->GetElement() == 0x1113) || (ElVal->GetElement() == 0x1114) ) ){ - FoundLength =4; + FoundLength =4; + ElVal->SetReadLength(4); // a bug is to be fixed } // end of fix @@ -661,7 +667,7 @@ void gdcmHeader::FixFoundLength(gdcmElValue * ElVal, guint32 FoundLength) { FoundLength =0; } - ElVal->SetLength(FoundLength); + ElVal->SetUsableLength(FoundLength); } /** @@ -744,7 +750,6 @@ void gdcmHeader::FixFoundLength(gdcmElValue * ElVal, guint32 FoundLength) { return; } FixFoundLength(ElVal, length32); - return; } @@ -768,7 +773,7 @@ void gdcmHeader::FixFoundLength(gdcmElValue * ElVal, guint32 FoundLength) { // appear when we find the first group with big endian encoding. This // is easy to detect since the length of a "Group Length" tag (the // ones with zero as element number) has to be of 4 (0x0004). When we - // encouter 1024 (0x0400) chances are the encoding changed and we + // encounter 1024 (0x0400) chances are the encoding changed and we // found a group with big endian encoding. // We shall use this second strategy. In order to make sure that we // can interpret the presence of an apparently big endian encoded @@ -821,6 +826,7 @@ void gdcmHeader::FixFoundLength(gdcmElValue * ElVal, guint32 FoundLength) { // not coexist in a Data Set and Data Sets nested within it".] // Length is on 4 bytes. FixFoundLength(ElVal, ReadInt32()); + return; } /** @@ -1244,6 +1250,7 @@ gdcmElValue * gdcmHeader::ReadNextElement(void) { NewElVal = NewElValueByNumber(g, n); FindVR(NewElVal); FindLength(NewElVal); + if (errno == 1) { // Call it quits return (gdcmElValue *)0; @@ -1768,7 +1775,7 @@ void gdcmHeader::LoadElements(void) { rewind(fp); // We don't use any longer the HashTable, since a lot a stuff is missing - // we SeQuences were encountered + // when SeQuences were encountered // //TagElValueHT ht = PubElValSet.GetTagHt(); //for (TagElValueHT::iterator tag = ht.begin(); tag != ht.end(); ++tag) {