From d9309280a40bdfcaf7889a28e61c71d4e188f9ee Mon Sep 17 00:00:00 2001 From: frog Date: Tue, 12 Nov 2002 11:57:48 +0000 Subject: [PATCH] * src/gdcmHeader::FindLength bug fix when trapping falsely explicit VR files. * src/gdcmHeader::FindVR: hard way fix of falsely explicit vr files. --- ChangeLog | 5 ++++ src/gdcm.h | 2 +- src/gdcmHeader.cxx | 62 +++++++++++++++++++++++++++++++++------------- 3 files changed, 51 insertions(+), 18 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4b64964d..e27716e7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2002-11-12 Eric Boix + * src/gdcmHeader::FindLength bug fix when trapping falsely explicit + VR files. + * src/gdcmHeader::FindVR: hard way fix of falsely explicit vr files. + 2002-11-7 Eric Boix * python/gdcm.i: added a typemap that converts a C++ hashing table to native Python dictionary. diff --git a/src/gdcm.h b/src/gdcm.h index 72a513a0..627e97ce 100644 --- a/src/gdcm.h +++ b/src/gdcm.h @@ -19,7 +19,7 @@ #include #include // For size_t #include -#include // CLEANME +#include // FIXME For FILE on GCC only #include // The requirement for the hash table (or map) that // we shall use: // 1/ First, next, last (iterators) diff --git a/src/gdcmHeader.cxx b/src/gdcmHeader.cxx index 2f5eac1c..1b81bf22 100644 --- a/src/gdcmHeader.cxx +++ b/src/gdcmHeader.cxx @@ -9,6 +9,7 @@ extern "C" { #else #include #endif +#include // for isalpha #include #include #include "gdcmUtil.h" @@ -267,15 +268,9 @@ void gdcmHeader::CheckSwap() void gdcmHeader::FindVR( ElValue *ElVal) { char VR[3]; + string vr; int lgrLue; long PositionOnEntry = ftell(fp); - - if (filetype != ExplicitVR) - return; - - lgrLue=fread (&VR, (size_t)2,(size_t)1, fp); - VR[2]=0; - // Warning: we believe this is explicit VR (Value Representation) because // we used a heuristic that found "UL" in the first tag. Alas this // doesn't guarantee that all the tags will be in explicit VR. In some @@ -283,17 +278,41 @@ void gdcmHeader::FindVR( ElValue *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; + + if (filetype != ExplicitVR) + return; - // FIXME There should be only one occurence returned. Avoid the - // first extraction by calling proper method. - VRAtr FoundVR = dicom_vr->find(string(VR))->first; - if ( ! FoundVR.empty()) { - ElVal->SetVR(FoundVR); + lgrLue=fread (&VR, (size_t)2,(size_t)1, fp); + VR[2]=0; + vr = string(VR); + + // 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) + // the dicom_vr dictionary with oddities like "\004\0" which crashes + // both GCC and VC++ implentations of the STL map. Hence when the + // expected VR read happens to be non-ascii characters we consider + // we hit falsely explicit VR tag. + + if ( (!isalpha(VR[0])) && (!isalpha(VR[1])) ) + RealExplicit = false; + + // CLEANME searching the dicom_vr at each occurence is expensive. + // PostPone this test in an optional integrity check at the end + // of parsing or only in debug mode. + if ( RealExplicit && !dicom_vr->count(vr) ) + RealExplicit = false; + + if ( RealExplicit ) { + 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"); fseek(fp, PositionOnEntry, SEEK_SET); } @@ -301,11 +320,10 @@ void gdcmHeader::FindVR( ElValue *ElVal) { void gdcmHeader::FindLength( ElValue * ElVal) { guint32 length32; guint16 length16; + string vr = ElVal->GetVR(); - if (filetype == ExplicitVR) { - string vr = ElVal->GetVR(); - if ( (vr != "Implicit") - && ( (vr=="OB") || (vr=="OW") || (vr=="SQ") || (vr=="UN") ) ) { + if ( (filetype == ExplicitVR) && (vr != "Implicit") ) { + if ( (vr=="OB") || (vr=="OW") || (vr=="SQ") || (vr=="UN") ) { // The following two bytes are reserved, so we skip them, // and we proceed on reading the length on 4 bytes. @@ -368,11 +386,12 @@ guint32 gdcmHeader::SwapLong(guint32 a) { /** * \ingroup gdcmHeader - * \brief remet les octets dans un ordre compatible avec celui du processeur + * \brief Swaps the bytes so they agree with the processor order * @return longueur retenue pour le champ */ guint16 gdcmHeader::SwapShort(guint16 a) { + //FIXME how could sw be equal to 2143 since we never set it this way ? if ( (sw==4321) || (sw==2143) ) a =(((a<<8) & 0x0ff00) | ((a>>8)&0x00ff)); return (a); @@ -383,6 +402,15 @@ void gdcmHeader::SkipElementValue(ElValue * ElVal) { (void)fseek(fp, (long)ElVal->GetLength(), SEEK_CUR); } +/** + * \ingroup gdcmHeader + * \brief Loads the element if it's size is not to big. + * @param ElVal Element whose value shall be loaded. + * @param MaxSize Size treshold above which the element value is not + * loaded in memory. The element value is allways loaded + * when MaxSize is equal to UINT32_MAX. + * @return + */ void gdcmHeader::LoadElementValue(ElValue * ElVal) { size_t item_read; guint16 group = ElVal->GetGroup(); -- 2.45.1