From 9ca4fd0ccbfea12ed7760856de3a8faf41625869 Mon Sep 17 00:00:00 2001 From: regrain Date: Fri, 7 Jan 2005 16:45:51 +0000 Subject: [PATCH] * src/gdcmDocEntry.[h|cxx] : now the ReadLength is the length of the datas to read in the file... and only it ! Length is the efective length of the datas in the DocEntry structure -- BeNours --- ChangeLog | 9 +++++-- src/gdcmBinEntry.cxx | 16 ++++++------- src/gdcmDocEntry.cxx | 19 +++++++-------- src/gdcmDocEntry.h | 50 ++++++++++++++++++-------------------- src/gdcmDocument.cxx | 57 ++++++++++++++++++++------------------------ src/gdcmDocument.h | 19 +++++++-------- src/gdcmSeqEntry.cxx | 10 ++++---- src/gdcmValEntry.cxx | 20 +++++++++------- 8 files changed, 98 insertions(+), 102 deletions(-) diff --git a/ChangeLog b/ChangeLog index a9ec6eff..f16b0960 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,12 @@ +2005-01-07 Benoit Regrain + * src/gdcmDocEntry.[h|cxx] : now the ReadLength is the length of the datas + to read in the file... and only it ! Length is the efective length of the + datas in the DocEntry structure + 2005-01-07 Mathieu Malaterre - * Change the gdcmDebug approach. Remov the global static debug 'dbg'. + * Change the gdcmDebug approach. Remov the global static debug 'dbg'. And now use a static function call instead, with a global variable. i - This is much closer to the VTK approach. Hopefully should be bulletproof + This is much closer to the VTK approach. Hopefully should be bulletproof and easier to use...hopefully 2005-01-06 Mathieu Malaterre diff --git a/src/gdcmBinEntry.cxx b/src/gdcmBinEntry.cxx index d382e73c..7515f648 100644 --- a/src/gdcmBinEntry.cxx +++ b/src/gdcmBinEntry.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmBinEntry.cxx,v $ Language: C++ - Date: $Date: 2005/01/06 20:03:26 $ - Version: $Revision: 1.43 $ + Date: $Date: 2005/01/07 16:45:51 $ + Version: $Revision: 1.44 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -42,10 +42,12 @@ BinEntry::BinEntry(DictEntry *e) : ValEntry(e) */ BinEntry::BinEntry(DocEntry *e) : ValEntry(e->GetDictEntry()) { - UsableLength = e->GetLength(); - ReadLength = e->GetReadLength(); - ImplicitVR = e->IsImplicitVR(); - Offset = e->GetOffset(); + Copy(e); +/* Length = e->GetLength(); + ReadLength = e->GetReadLength(); + ImplicitVR = e->IsImplicitVR(); + Offset = e->GetOffset();*/ + //FIXME //SQDepthLevel = e->GetDepthLevel(); @@ -114,8 +116,6 @@ void BinEntry::WriteContent(std::ofstream *fp, FileType filetype) { // there is a 'non string' LUT, overlay, etc fp->write ( (char*)binArea, lgr ); // Elem value - //assert( strlen((char*)binArea) == lgr ); - } else { diff --git a/src/gdcmDocEntry.cxx b/src/gdcmDocEntry.cxx index 8c750d71..c1317163 100644 --- a/src/gdcmDocEntry.cxx +++ b/src/gdcmDocEntry.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmDocEntry.cxx,v $ Language: C++ - Date: $Date: 2005/01/06 20:03:27 $ - Version: $Revision: 1.38 $ + Date: $Date: 2005/01/07 16:45:51 $ + Version: $Revision: 1.39 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -47,7 +47,7 @@ DocEntry::DocEntry(DictEntry *in) // init some variables ReadLength = 0; - UsableLength = 0; + Length = 0; } //----------------------------------------------------------------------------- @@ -76,7 +76,7 @@ void DocEntry::Print(std::ostream &os) if (PrintLevel >= 2) { s << " lg : "; - lgth = GetReadLength(); // ReadLength, as opposed to UsableLength + lgth = GetReadLength(); // ReadLength, as opposed to Length if (lgth == 0xffffffff) { st = Util::Format("x(ffff)"); // I said : "x(ffff)" ! @@ -126,7 +126,7 @@ void DocEntry::WriteContent(std::ofstream *fp, FileType filetype) uint16_t group = GetGroup(); VRKey vr = GetVR(); uint16_t el = GetElement(); - uint32_t lgr = GetReadLength(); + uint32_t lgr = GetLength(); if ( group == 0xfffe && el == 0x0000 ) { @@ -246,11 +246,10 @@ uint32_t DocEntry::GetFullLength() */ void DocEntry::Copy (DocEntry *e) { -// DicomDict = e->DicomDict; - UsableLength = e->UsableLength; - ReadLength = e->ReadLength; - ImplicitVR = e->ImplicitVR; - Offset = e->Offset; + Length = e->Length; + ReadLength = e->ReadLength; + ImplicitVR = e->ImplicitVR; + Offset = e->Offset; // TODO : remove DocEntry SQDepth } diff --git a/src/gdcmDocEntry.h b/src/gdcmDocEntry.h index 5a95fe0a..5f434ca0 100644 --- a/src/gdcmDocEntry.h +++ b/src/gdcmDocEntry.h @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmDocEntry.h,v $ Language: C++ - Date: $Date: 2005/01/07 16:14:58 $ - Version: $Revision: 1.36 $ + Date: $Date: 2005/01/07 16:45:51 $ + Version: $Revision: 1.37 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -80,11 +80,11 @@ public: /// \warning offset of the *value*, not of the Dicom Header Entry size_t GetOffset() { return Offset; }; - /// \brief Returns the actual value length of the current Dicom Header Entry - /// \warning this value is not *always* the one stored in the Dicom Header - /// in case of well knowned bugs - uint32_t GetLength() { return UsableLength; }; - + + /// \brief Sets only 'Read Length' (*not* 'Usable Length') of the current + /// Dicom Header Entry + void SetReadLength(uint32_t l) { ReadLength = l; }; + /// \brief Returns the 'read length' of the current Dicom Header Entry /// \warning this value is the one stored in the Dicom Header but not /// mandatoryly the one thats's used (in case on SQ, or delimiters, @@ -93,17 +93,15 @@ public: /// \brief Sets both 'Read Length' and 'Usable Length' of the current /// Dicom Header Entry - void SetLength(uint32_t l) { ReadLength = UsableLength = l; }; + void SetLength(uint32_t l) { Length = l; }; - // The following 3 members, for internal use only ! - - /// \brief Sets only 'Read Length' (*not* 'Usable Length') of the current - /// Dicom Header Entry - void SetReadLength(uint32_t l) { ReadLength = l; }; + /// \brief Returns the actual value length of the current Dicom Header Entry + /// \warning this value is not *always* the one stored in the Dicom Header + /// in case of well knowned bugs + uint32_t GetLength() { return Length; }; + - /// \brief Sets only 'Usable Length' (*not* 'Read Length') of the current - /// Dicom Header Entry - void SetUsableLength(uint32_t l) { UsableLength = l; }; + // The following 3 members, for internal use only ! /// \brief Sets the offset of the Dicom Element /// \warning use with caution ! @@ -144,24 +142,17 @@ public: virtual void Print (std::ostream &os = std::cout); -private: - // FIXME: In fact we should be more specific and use : - // friend DocEntry * Header::ReadNextElement(void); - friend class Header; - protected: // Variables /// \brief pointer to the underlying Dicom dictionary element DictEntry *DicomDict; - /// \brief Updated from ReadLength, by FixFoungLentgh() for fixing a bug - /// in the header or helping the parser going on - uint32_t UsableLength; + /// \brief Correspond to the real length of the datas + /// This length might always be even + uint32_t Length; - /// \brief 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. + /// \brief Length to read in the file to obtain datas. uint32_t ReadLength; /// \brief Even when reading explicit vr files, some elements happen to @@ -175,6 +166,11 @@ protected: /// \brief Generalized key of this DocEntry (for details on /// the generalized key refer to \ref TagKey documentation). TagKey Key; + +private: + // FIXME: In fact we should be more specific and use : + // friend DocEntry * Header::ReadNextElement(void); + friend class Header; }; } // end namespace gdcm //----------------------------------------------------------------------------- diff --git a/src/gdcmDocument.cxx b/src/gdcmDocument.cxx index 45b8fb97..313cee7a 100644 --- a/src/gdcmDocument.cxx +++ b/src/gdcmDocument.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmDocument.cxx,v $ Language: C++ - Date: $Date: 2005/01/07 16:26:12 $ - Version: $Revision: 1.163 $ + Date: $Date: 2005/01/07 16:45:51 $ + Version: $Revision: 1.164 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -1180,7 +1180,6 @@ void Document::ParseDES(DocEntrySet *set, long offset, SeqEntry *newSeqEntry; VRKey vr; bool used=false; - long offsetEntry,readEntry; while (true) { @@ -1203,9 +1202,6 @@ void Document::ParseDES(DocEntrySet *set, long offset, if ( newValEntry || newBinEntry ) { - offsetEntry=newDocEntry->GetOffset(); - readEntry=newDocEntry->GetReadLength(); - if ( newBinEntry ) { if ( ! Global::GetVR()->IsVROfBinaryRepresentable(vr) ) @@ -1301,9 +1297,9 @@ void Document::ParseDES(DocEntrySet *set, long offset, Fp->seekg( positionOnEntry, std::ios::beg ); } } - + // Just to make sure we are at the beginning of next entry. - SkipToNextDocEntry(offsetEntry,readEntry); + SkipToNextDocEntry(newDocEntry); } else { @@ -1500,7 +1496,7 @@ void Document::LoadDocEntry(DocEntry *entry) LoadEntryBinArea(binEntryPtr); // last one, not to erase length ! return; } - + /// \todo Any compacter code suggested (?) if ( IsDocEntryAnInteger(entry) ) { @@ -1562,7 +1558,7 @@ void Document::LoadDocEntry(DocEntry *entry) //Debug::Verbose(0, "Warning: bad length: ", length ); Debug::Verbose(0, "For string :", newValue.c_str()); // Since we change the length of string update it length - entry->SetReadLength(length+1); + //entry->SetReadLength(length+1); } else { @@ -1624,9 +1620,7 @@ void Document::FindDocEntryLength( DocEntry *entry ) uint32_t lengthOB; try { - /// \todo rename that to FindDocEntryLengthOBOrOW since - /// the above test is on both OB and OW... - lengthOB = FindDocEntryLengthOB(); + lengthOB = FindDocEntryLengthOBOrOW(); } catch ( FormatUnexpected ) { @@ -1637,11 +1631,15 @@ void Document::FindDocEntryLength( DocEntry *entry ) // the length and proceed. long currentPosition = Fp->tellg(); Fp->seekg(0L,std::ios::end); + long lengthUntilEOF = (long)(Fp->tellg())-currentPosition; Fp->seekg(currentPosition, std::ios::beg); + + entry->SetReadLength(lengthUntilEOF); entry->SetLength(lengthUntilEOF); return; } + entry->SetReadLength(lengthOB); entry->SetLength(lengthOB); return; } @@ -1690,6 +1688,7 @@ void Document::FindDocEntryLength( DocEntry *entry ) } length16 = 4; SwitchSwapToBigEndian(); + // Restore the unproperly loaded values i.e. the group, the element // and the dictionary entry depending on them. uint16_t correctGroup = SwapShort( entry->GetGroup() ); @@ -1926,10 +1925,10 @@ void Document::SkipDocEntry(DocEntry *entry) * @param readLgth length to skip */ -void Document::SkipToNextDocEntry(long offset,long readLgth) +void Document::SkipToNextDocEntry(DocEntry *newDocEntry) { - Fp->seekg((long)(offset), std::ios::beg); - Fp->seekg( (long)(readLgth), std::ios::cur); + Fp->seekg((long)(newDocEntry->GetOffset()), std::ios::beg); + Fp->seekg( (long)(newDocEntry->GetReadLength()),std::ios::cur); } /** @@ -1948,15 +1947,15 @@ void Document::FixDocEntryFoundLength(DocEntry *entry, foundLength = 0; } - uint16_t gr = entry->GetGroup(); - uint16_t el = entry->GetElement(); + uint16_t gr = entry->GetGroup(); + uint16_t elem = entry->GetElement(); if ( foundLength % 2) { std::ostringstream s; s << "Warning : Tag with uneven length " << foundLength - << " in x(" << std::hex << gr << "," << el <<")" << std::dec; + << " in x(" << std::hex << gr << "," << elem <<")" << std::dec; Debug::Verbose(0, s.str().c_str()); } @@ -1969,9 +1968,7 @@ void Document::FixDocEntryFoundLength(DocEntry *entry, if ( foundLength == 13) { // Only happens for this length ! - if ( entry->GetGroup() != 0x0008 - || ( entry->GetElement() != 0x0070 - && entry->GetElement() != 0x0080 ) ) + if ( gr != 0x0008 || ( elem != 0x0070 && elem != 0x0080 ) ) { foundLength = 10; entry->SetReadLength(10); /// \todo a bug is to be fixed !? @@ -1982,9 +1979,7 @@ void Document::FixDocEntryFoundLength(DocEntry *entry, // Occurence of such images is quite low (unless one leaves close to a // 'Leonardo' source. Hence, one might consider commenting out the // following fix on efficiency reasons. - else if ( entry->GetGroup() == 0x0009 - && ( entry->GetElement() == 0x1113 - || entry->GetElement() == 0x1114 ) ) + else if ( gr == 0x0009 && ( elem == 0x1113 || elem == 0x1114 ) ) { foundLength = 4; entry->SetReadLength(4); /// \todo a bug is to be fixed !? @@ -1998,7 +1993,7 @@ void Document::FixDocEntryFoundLength(DocEntry *entry, //////// We encountered a 'delimiter' element i.e. a tag of the form // "fffe|xxxx" which is just a marker. Delimiters length should not be // taken into account. - else if( entry->GetGroup() == 0xfffe ) + else if( gr == 0xfffe ) { // According to the norm, fffe|0000 shouldn't exist. BUT the Philips // image gdcmData/gdcm-MR-PHILIPS-16-Multi-Seq.dcm happens to @@ -2009,7 +2004,7 @@ void Document::FixDocEntryFoundLength(DocEntry *entry, } } - entry->SetUsableLength(foundLength); + entry->SetLength(foundLength); } /** @@ -2066,7 +2061,7 @@ bool Document::IsDocEntryAnInteger(DocEntry *entry) * @return */ -uint32_t Document::FindDocEntryLengthOB() +uint32_t Document::FindDocEntryLengthOBOrOW() throw( FormatUnexpected ) { // See PS 3.5-2001, section A.4 p. 49 on encapsulation of encoded pixel data. @@ -2085,7 +2080,7 @@ uint32_t Document::FindDocEntryLengthOB() } catch ( FormatError ) { - throw FormatError("Document::FindDocEntryLengthOB()", + throw FormatError("Document::FindDocEntryLengthOBOrOW()", " group or element not present."); } @@ -2094,10 +2089,10 @@ uint32_t Document::FindDocEntryLengthOB() if ( group != 0xfffe || ( ( elem != 0xe0dd ) && ( elem != 0xe000 ) ) ) { - Debug::Verbose(1, "Document::FindDocEntryLengthOB: neither an Item " + Debug::Verbose(1, "Document::FindDocEntryLengthOBOrOW: neither an Item " "tag nor a Sequence delimiter tag."); Fp->seekg(positionOnEntry, std::ios::beg); - throw FormatUnexpected("Document::FindDocEntryLengthOB()", + throw FormatUnexpected("Document::FindDocEntryLengthOBOrOW()", "Neither an Item tag nor a Sequence " "delimiter tag."); } diff --git a/src/gdcmDocument.h b/src/gdcmDocument.h index bacbe5cf..1c844795 100644 --- a/src/gdcmDocument.h +++ b/src/gdcmDocument.h @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmDocument.h,v $ Language: C++ - Date: $Date: 2005/01/07 08:46:18 $ - Version: $Revision: 1.76 $ + Date: $Date: 2005/01/07 16:45:51 $ + Version: $Revision: 1.77 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -208,20 +208,19 @@ private: void LoadDocEntry (DocEntry *e); void FindDocEntryLength (DocEntry *e) throw ( FormatError ); + uint32_t FindDocEntryLengthOBOrOW() throw( FormatUnexpected ); std::string FindDocEntryVR(); bool CheckDocEntryVR (VRKey k); - std::string GetDocEntryValue (DocEntry *e); - std::string GetDocEntryUnvalue(DocEntry *e); + std::string GetDocEntryValue (DocEntry *entry); + std::string GetDocEntryUnvalue(DocEntry *entry); - void SkipDocEntry (DocEntry *e); - void SkipToNextDocEntry (long offset,long readLgth); + void SkipDocEntry (DocEntry *entry); + void SkipToNextDocEntry (DocEntry *entry); - void FixDocEntryFoundLength(DocEntry *e, uint32_t l); - bool IsDocEntryAnInteger (DocEntry *e); - - uint32_t FindDocEntryLengthOB() throw( FormatUnexpected ); + void FixDocEntryFoundLength(DocEntry *entry,uint32_t l); + bool IsDocEntryAnInteger (DocEntry *entry); uint16_t ReadInt16() throw ( FormatError ); uint32_t ReadInt32() throw ( FormatError ); diff --git a/src/gdcmSeqEntry.cxx b/src/gdcmSeqEntry.cxx index 1962d89f..9f2c4d19 100644 --- a/src/gdcmSeqEntry.cxx +++ b/src/gdcmSeqEntry.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmSeqEntry.cxx,v $ Language: C++ - Date: $Date: 2005/01/06 20:03:28 $ - Version: $Revision: 1.41 $ + Date: $Date: 2005/01/07 16:45:52 $ + Version: $Revision: 1.42 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -38,8 +38,8 @@ namespace gdcm SeqEntry::SeqEntry( DictEntry *e ) : DocEntry(e) { - UsableLength = 0; - ReadLength = 0xffffffff; + Length = 0; + ReadLength = 0xffffffff; SQDepthLevel = -1; DelimitorMode = false; @@ -54,7 +54,7 @@ SeqEntry::SeqEntry( DictEntry *e ) SeqEntry::SeqEntry( DocEntry *e, int depth ) : DocEntry( e->GetDictEntry() ) { - UsableLength = 0; + Length = 0; ReadLength = 0xffffffff; SQDepthLevel = depth; diff --git a/src/gdcmValEntry.cxx b/src/gdcmValEntry.cxx index 6b81bad9..ada7ecf6 100644 --- a/src/gdcmValEntry.cxx +++ b/src/gdcmValEntry.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmValEntry.cxx,v $ Language: C++ - Date: $Date: 2005/01/06 20:03:28 $ - Version: $Revision: 1.42 $ + Date: $Date: 2005/01/07 16:45:52 $ + Version: $Revision: 1.43 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -47,10 +47,11 @@ ValEntry::ValEntry(DictEntry *e) : DocEntry(e) ValEntry::ValEntry(DocEntry *e) : DocEntry(e->GetDictEntry()) { - UsableLength = e->GetLength(); - ReadLength = e->GetReadLength(); - ImplicitVR = e->IsImplicitVR(); - Offset = e->GetOffset(); + Copy(e); +/* Length = e->GetLength(); + ReadLength = e->GetReadLength(); + ImplicitVR = e->IsImplicitVR(); + Offset = e->GetOffset();*/ } @@ -223,13 +224,14 @@ void ValEntry::WriteContent(std::ofstream *fp, FileType filetype) { DocEntry::WriteContent(fp, filetype); - if ( GetGroup() == 0xfffe ) + if ( GetGroup() == 0xfffe ) { return; //delimitors have NO value } - + std::string vr = GetVR(); - unsigned int lgr = GetReadLength(); + unsigned int lgr = GetLength(); + //std::cout<