X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=src%2FgdcmDocument.cxx;h=a52ab8cd53c9edf2e15a5092ccdb8f71157ac4b8;hb=c35def1dd9b5d8ba9bb1e058da5c42912f599643;hp=c2754559da0d9946c7ea82506abc8bcb0f8401ff;hpb=8fd45dc6d321d1419854dc0e4fa6a37d6826b655;p=gdcm.git diff --git a/src/gdcmDocument.cxx b/src/gdcmDocument.cxx index c2754559..a52ab8cd 100644 --- a/src/gdcmDocument.cxx +++ b/src/gdcmDocument.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmDocument.cxx,v $ Language: C++ - Date: $Date: 2007/05/23 14:18:09 $ - Version: $Revision: 1.358 $ + Date: $Date: 2007/06/18 15:44:52 $ + Version: $Revision: 1.362 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -70,6 +70,8 @@ Document::Document() LoadMode = LD_ALL; // default : load everything, later SetFileName(""); + changeFromUN=false; + UnexpectedEOF=false; } /** @@ -918,7 +920,7 @@ bool Document::operator<(Document &document) /** * \brief Reads a given length of bytes - * (in order to avoid to many CPU time consuming fread-s) + * (in order to avoid to many CPU time-consuming fread-s) * @param l length to read */ void Document::ReadBegBuffer(size_t l) @@ -1282,11 +1284,11 @@ void Document::ParseDES(DocEntrySet *set, long offset, << " at offset 0x(" << std::hex << newDocEntry->GetOffset() << ")"); - ParseSQ( newSeqEntry, - newDocEntry->GetOffset(), - l, delim_mode_intern); + bool res = ParseSQ( newSeqEntry, + newDocEntry->GetOffset(), + l, delim_mode_intern); - gdcmDebugMacro( "Exit from ParseSQ, delim " << delim_mode_intern); + gdcmDebugMacro( "Exit from ParseSQ, delim " << delim_mode_intern << " -->return : " << res); } if ( !set->AddEntry( newSeqEntry ) ) { @@ -1318,15 +1320,18 @@ void Document::ParseDES(DocEntrySet *set, long offset, newDocEntry->Delete(); } first = false; + + if (UnexpectedEOF) // some terminator was missing + break; } // end While gdcmDebugMacro( "Exit from ParseDES, delim-mode " << delim_mode ); } /** * \brief Parses a Sequence ( SeqEntry after SeqEntry) - * @return parsed length for this level + * @return false if expected fff0,e000 not found */ -void Document::ParseSQ( SeqEntry *seqEntry, +bool Document::ParseSQ( SeqEntry *seqEntry, long offset, long l_max, bool delim_mode) { int SQItemNumber = 0; @@ -1339,9 +1344,12 @@ void Document::ParseSQ( SeqEntry *seqEntry, DocEntry *newDocEntry = ReadNextDocEntry(); if ( !newDocEntry ) - { + { + // The most frequent is when a SQ terminator is missing (?!?) gdcmWarningMacro("in ParseSQ : should never get here!"); - break; + UnexpectedEOF = true; + return false; + //break; } if ( delim_mode ) { @@ -1389,6 +1397,7 @@ void Document::ParseSQ( SeqEntry *seqEntry, break; } } + return true; } /** @@ -1502,12 +1511,12 @@ void Document::FindDocEntryLength( DocEntry *entry ) { const VRKey &vr = entry->GetVR(); uint16_t length16; - if ( Filetype == ExplicitVR && !entry->IsImplicitVR() ) { if ( vr == "OB" || vr == "OW" || vr == "SQ" || vr == "UT" - || vr == "UN" ) + || vr == "UN" || changeFromUN == true) { + changeFromUN = false; // The following reserved two bytes (see PS 3.5-2003, section // "7.1.2 Data element structure with explicit vr", p 27) must be // skipped before proceeding on reading the length on 4 bytes. @@ -1549,11 +1558,9 @@ void Document::FindDocEntryLength( DocEntry *entry ) FixDocEntryFoundLength(entry, length32); return; } - // Length is encoded on 2 bytes. //length16 = ReadInt16(); length16 = GetInt16(); - // 0xffff means that we deal with 'No Length' Sequence // or 'No Length' SQItem if ( length16 == 0xffff) @@ -2062,8 +2069,7 @@ bool Document::CheckSwap() s16 = *((uint16_t *)(deb)); gdcmDebugMacro("not a DicomV3 nor a 'clean' ACR/NEMA;" - << " (->despaired wild guesses !)"); - + << " (->despaired wild guesses !)"); switch ( s16 ) { case 0x0001 : @@ -2091,9 +2097,45 @@ bool Document::CheckSwap() Filetype = ACR; return true; default : - gdcmWarningMacro("ACR/NEMA unfound swap info (Hopeless !)"); - Filetype = Unknown; - return false; + + s16 = *((uint16_t *)(deb)); + if (s16 != 0x0000) + return false; + s16 = *((uint16_t *)(deb+2)); + + Fp->seekg ( 0L, std::ios::beg); // Once per Document + CurrentOffsetPosition = 0; + switch(s16) // try an other trick! + // -> to be able to decode 0029|1010 DataElement + // -> and be not less cleaver than dcmdump ;-) + { + case 0x0004 : + SwapCode = 1234; + break; + case 0x0400 : + SwapCode = 3412; + break; + default: + gdcmWarningMacro("ACR/NEMA unfound swap info (Hopeless !)"); + Filetype = Unknown; + return false; + } + // Check if next 2 bytes are a VR + // Probabely something more time-consuming exists with std::string + const char VRvalues[] = "AEASCSDADSFLFDISLOLTPNSHSLSSSTTMUIULUSUTOBOWOFATUNSQ"; + int nbVal = 26; + const char *pt = VRvalues; + for (int i=0;iGetVR(); + dictEntry->Unregister(); // GetDictEntry registered it + + // for VR = "UN", length is always stored on 4 bytes. + changeFromUN=true; + /// \todo : fixme If inside a supposed to be UN DataElement (but SQ according to a private dictionnary) + /// there is some more supposed to UN DataElements, it will probabely fail. + /// --> find a -non time consuming- trick to store changeFromUN info at DataElement level, + /// not at the Document level. + } + } + + DocEntry *newEntry; //if ( Global::GetVR()->IsVROfSequence(realVR) ) if (realVR == "SQ")