From 8e657a0766489604ade10a101d0d8995bcb79280 Mon Sep 17 00:00:00 2001 From: frog Date: Thu, 14 Nov 2002 14:55:20 +0000 Subject: [PATCH] * python/testSuite.py unittest test suite added (uses Data) * Data/* dcm and acr files for the test suite. * glib dependance removed from un*x version. We now use ISO C99 7.18 Integer types (see stdint.h) - python/Makefile, src/Makefile src/gdcm.h * src/ when an explicit vr (like dicom files) suddenly poped an implicit element we use to mark the underlying DictEntry of the concerned ElValue with "Implicit". This strategy was damageable too the public or provite dictionaries, since some of their vr would be changed. Since Header::FindLength heavily relies on the detection by Header::FindVR of falsely explicit elements, I added an extra ImplicitVr member to ElValue (boolean). The rest of the changes we the necessary adaptations. --- Frog --- ChangeLog | 15 +++++++++++++++ TODO | 7 ++++++- src/Makefile | 3 +-- src/gdcm.h | 27 +++++++++++++++++++++++---- src/gdcmDictEntry.cxx | 21 +++++++++++++++++++++ src/gdcmElValue.cxx | 5 ++++- src/gdcmHeader.cxx | 37 +++++++++++++++++++++---------------- src/gdcmUtil.cxx | 2 +- 8 files changed, 92 insertions(+), 25 deletions(-) diff --git a/ChangeLog b/ChangeLog index e27716e7..cb104f8c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2002-11-14 Eric Boix + * python/testSuite.py unittest test suite added (uses Data) + * Data/* dcm and acr files for the test suite. + * glib dependance removed from un*x version. We now use ISO C99 + 7.18 Integer types (see stdint.h) + - python/Makefile, src/Makefile src/gdcm.h + * src/ when an explicit vr (like dicom files) suddenly poped an + implicit element we use to mark the underlying DictEntry of the + concerned ElValue with "Implicit". This strategy was damageable + too the public or provite dictionaries, since some of their vr + would be changed. Since Header::FindLength heavily relies on the + detection by Header::FindVR of falsely explicit elements, I + added an extra ImplicitVr member to ElValue (boolean). + The rest of the changes we the necessary adaptations. + 2002-11-12 Eric Boix * src/gdcmHeader::FindLength bug fix when trapping falsely explicit VR files. diff --git a/TODO b/TODO index f7a7dd60..42235948 100644 --- a/TODO +++ b/TODO @@ -1,3 +1,8 @@ +* Group length is not a unique tag in a file. Hence avoid putting it + in the element values dictionary without doing something smarter + (say, instead of storing the length store the group and the length + so we can related a length to a group). + GetPubElValByNumber doit faire la difference entre chaine vide et chaine pas touve''. Eventuellement raiser une exception ? @@ -11,7 +16,7 @@ gdcmHeader::ReadNextElement: retarder le stockage en mem des gros elements * fournir une method qui ne fait que lire les elements passes en arguments sous forme d'une liste. -grep str2num *.c: c'est une macro sans doute proprifiable +grep str2num *.cxx: c'est une macro sans doute proprifiable gdcmHeader::CheckSwap() dans le cas ACR pas propre, degager tout de suite si on a deduit que c'en est pas... diff --git a/src/Makefile b/src/Makefile index d2f92c56..bd17a737 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,6 +1,5 @@ -CXXFLAGS=`glib-config --cflags` CPPFLAGS=-g -Wall -Wunused-variable -LDFLAGS=`glib-config --libs` -g +LDFLAGS=-g OBJECTS=gdcmUtil.o \ gdcmHeader.o \ diff --git a/src/gdcm.h b/src/gdcm.h index 627e97ce..6a43de04 100644 --- a/src/gdcm.h +++ b/src/gdcm.h @@ -18,7 +18,6 @@ #include #include #include // For size_t -#include #include // FIXME For FILE on GCC only #include // The requirement for the hash table (or map) that // we shall use: @@ -29,6 +28,16 @@ // 3/ Make sure we can setup some default size value, // which should be around 4500 entries which is the // average dictionary size (said JPR) +#ifdef __GNUC__ +#include +#define guint16 uint16_t +#define guint32 uint32_t +#define g_malloc malloc +#define g_free free +#endif +#ifdef _MSC_VER +#include +#endif #ifdef _MSC_VER using namespace std; // string type lives in the std namespace on VC++ @@ -79,12 +88,15 @@ private: public: //CLEANME gdcmDictEntry(); gdcmDictEntry(guint16 group, guint16 element, - string vr, string fourth, string name); + string vr = "Unknown", + string fourth = "Unknown", + string name = "Unknown"); static TagKey TranslateToKey(guint16 group, guint16 element); guint16 GetGroup(void) { return group;}; guint16 GetElement(void){return element;}; string GetVR(void) {return vr; }; - void SetVR(string in){vr = in; }; + void SetVR(string); + bool IsVrUnknown(void); string GetFourth(void) {return fourth;}; string GetName(void) {return name;}; string GetKey(void) {return key;}; @@ -141,6 +153,10 @@ class GDCM_EXPORT ElValue { private: gdcmDictEntry *entry; guint32 LgrElem; + 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. // Might prove of some interest (see _ID_DCM_ELEM) // int Swap; public: @@ -149,11 +165,14 @@ public: ElValue(gdcmDictEntry*); void SetVR(string); string GetVR(void); + bool IsVrUnknown(void) { return entry->IsVrUnknown(); }; void SetLength(guint32 l){LgrElem = l; }; void SetValue(string val){ value = val; }; void SetOffset(size_t of){ Offset = of; }; + void SetImplicitVr(void) { ImplicitVr = true; }; + bool IsImplicitVr(void) { return ImplicitVr; }; string GetValue(void) { return value; }; - guint32 GetLength(void) { return LgrElem; }; + guint32 GetLength(void) { return LgrElem; }; size_t GetOffset(void) { return Offset; }; guint16 GetGroup(void) { return entry->GetGroup(); }; guint16 GetElement(void) { return entry->GetElement(); }; diff --git a/src/gdcmDictEntry.cxx b/src/gdcmDictEntry.cxx index ddfd3e00..0294d7b5 100644 --- a/src/gdcmDictEntry.cxx +++ b/src/gdcmDictEntry.cxx @@ -1,4 +1,5 @@ #include "gdcm.h" +#include "gdcmUtil.h" gdcmDictEntry::gdcmDictEntry(guint16 InGroup, guint16 InElement, string InVr, string InFourth, string InName) @@ -21,3 +22,23 @@ TagKey gdcmDictEntry::TranslateToKey(guint16 group, guint16 element) { key = trash; // Convertion through assignement return key; } + +/** + * \ingroup gdcmDictEntry + * \brief If-and only if-the vr is unset then overwrite it. + * @param NewVr New vr to be set. + */ +void gdcmDictEntry::SetVR(string NewVr) { + if ( IsVrUnknown() ) + vr = NewVr; + else { + dbg.Error(true, "gdcmDictEntry::SetVR", + "Overwriting vr might compromise a dictionary"); + } +} + +bool gdcmDictEntry::IsVrUnknown() { + if ( vr == "Unknown" ) + return true; + return false; +} diff --git a/src/gdcmElValue.cxx b/src/gdcmElValue.cxx index 5194a799..bbcf731c 100644 --- a/src/gdcmElValue.cxx +++ b/src/gdcmElValue.cxx @@ -3,4 +3,7 @@ void ElValue::SetVR(string ValRep) { entry->SetVR(ValRep); } string ElValue::GetVR(void) { return entry->GetVR(); } -ElValue::ElValue(gdcmDictEntry* in) { entry = in; } +ElValue::ElValue(gdcmDictEntry* in) { + ImplicitVr = false; + entry = in; +} diff --git a/src/gdcmHeader.cxx b/src/gdcmHeader.cxx index 1b81bf22..b886afe2 100644 --- a/src/gdcmHeader.cxx +++ b/src/gdcmHeader.cxx @@ -1,7 +1,4 @@ #include "gdcm.h" -extern "C" { -#include "glib.h" -} #include // For nthos: #ifdef _MSC_VER @@ -154,21 +151,21 @@ void gdcmHeader::CheckSwap() entCur = deb + 136; if(memcmp(entCur, "UL", (size_t)2) == 0) { filetype = ExplicitVR; - dbg.Verbose(0, "gdcmHeader::CheckSwap:", + dbg.Verbose(1, "gdcmHeader::CheckSwap:", "explicit Value Representation"); } else { filetype = ImplicitVR; - dbg.Verbose(0, "gdcmHeader::CheckSwap:", + dbg.Verbose(1, "gdcmHeader::CheckSwap:", "not an explicit Value Representation"); } if (net2host) { sw = 4321; - dbg.Verbose(0, "gdcmHeader::CheckSwap:", + dbg.Verbose(1, "gdcmHeader::CheckSwap:", "HostByteOrder != NetworkByteOrder"); } else { sw = 0; - dbg.Verbose(0, "gdcmHeader::CheckSwap:", + dbg.Verbose(1, "gdcmHeader::CheckSwap:", "HostByteOrder = NetworkByteOrder"); } @@ -305,16 +302,23 @@ void gdcmHeader::FindVR( ElValue *ElVal) { RealExplicit = false; if ( RealExplicit ) { - ElVal->SetVR(vr); + if ( ElVal->IsVrUnknown() ) + ElVal->SetVR(vr); return; } // We thought this was explicit VR, but we end up with an // implicit VR tag. Let's backtrack. - dbg.Verbose(1, "gdcmHeader::FindVR:", - "Falsely explicit vr file"); - ElVal->SetVR("Implicit"); + dbg.Verbose(1, "gdcmHeader::FindVR:", "Falsely explicit vr file"); 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(); } void gdcmHeader::FindLength( ElValue * ElVal) { @@ -322,7 +326,7 @@ void gdcmHeader::FindLength( ElValue * ElVal) { guint16 length16; string vr = ElVal->GetVR(); - if ( (filetype == ExplicitVR) && (vr != "Implicit") ) { + if ( (filetype == ExplicitVR) && ! ElVal->IsImplicitVr() ) { if ( (vr=="OB") || (vr=="OW") || (vr=="SQ") || (vr=="UN") ) { // The following two bytes are reserved, so we skip them, @@ -417,6 +421,7 @@ void gdcmHeader::LoadElementValue(ElValue * ElVal) { guint16 elem = ElVal->GetElement(); string vr = ElVal->GetVR(); guint32 length = ElVal->GetLength(); + fseek(fp, (long)ElVal->GetOffset(), SEEK_SET); // Sequences not treated yet ! @@ -515,7 +520,7 @@ ElValue * gdcmHeader::ReadNextElement(void) { // Find out if the tag we encountered is in the dictionaries: gdcmDictEntry * NewTag = IsInDicts(g, n); if (!NewTag) - NewTag = new gdcmDictEntry(g, n, "Unknown", "Unknown", "Unknown"); + NewTag = new gdcmDictEntry(g, n); NewElVal = new ElValue(NewTag); if (!NewElVal) { @@ -531,9 +536,9 @@ ElValue * gdcmHeader::ReadNextElement(void) { bool gdcmHeader::IsAnInteger(guint16 group, guint16 element, string vr, guint32 length ) { - // When we have some semantics on the element we just read, and we - // a priori now we are dealing with an integer, then we can swap it's - // element value properly. + // 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 + // able to swap it's element value properly. if ( element == 0 ) { // This is the group length of the group if (length != 4) dbg.Error("gdcmHeader::ShouldBeSwaped", "should be four"); diff --git a/src/gdcmUtil.cxx b/src/gdcmUtil.cxx index ac84c824..78bcff73 100644 --- a/src/gdcmUtil.cxx +++ b/src/gdcmUtil.cxx @@ -1,4 +1,4 @@ -#include +#include // For isspace #include "gdcmUtil.h" gdcmDebug::gdcmDebug(int level) { -- 2.45.0