X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;ds=sidebyside;f=src%2FgdcmDocument.cxx;h=c339fa44ff53f8a59dbe98c6d4cdd58a91b9a175;hb=4b19bf900463affaf44f2a0f3b4db6ec575bc7b2;hp=d56b0527fe202a244da9553f3d51aab0a17eabb7;hpb=cbc5aa46f89e8b5b4b1d965b32392139668abc16;p=gdcm.git diff --git a/src/gdcmDocument.cxx b/src/gdcmDocument.cxx index d56b0527..c339fa44 100644 --- a/src/gdcmDocument.cxx +++ b/src/gdcmDocument.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmDocument.cxx,v $ Language: C++ - Date: $Date: 2006/03/01 10:15:12 $ - Version: $Revision: 1.343 $ + Date: $Date: 2006/05/30 08:10:19 $ + Version: $Revision: 1.349 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -95,19 +95,22 @@ bool Document::Load( ) return DoTheLoadingDocumentJob( ); } -#ifndef GDCM_LEGACY_REMOVE + +//#ifndef GDCM_LEGACY_REMOVE /** * \brief Loader. (DEPRECATED : not to break the API) * @param fileName 'Document' (File or DicomDir) to be open for parsing * @return false if file cannot be open or no swap info was found, * or no tag was found. */ + /* bool Document::Load( std::string const &fileName ) { Filename = fileName; return DoTheLoadingDocumentJob( ); } -#endif +*/ +//#endif /** * \brief Performs the Loading Job (internal use only) @@ -260,7 +263,7 @@ bool Document::DoTheLoadingDocumentJob( ) LoadDocEntry(d, true); } - CloseFile(); + CloseFile(); // ---------------------------- // Specific code to allow gdcm to read ACR-LibIDO formated images @@ -695,7 +698,6 @@ void Document::WriteContent(std::ofstream *fp, FileType filetype) fp->write(filePreamble, 128); fp->write("DICM", 4); } - /* * \todo rewrite later, if really usefull * - 'Group Length' element is optional in DICOM @@ -1047,13 +1049,13 @@ void Document::ParseDES(DocEntrySet *set, long offset, DocEntry *newDocEntry; DataEntry *newDataEntry; SeqEntry *newSeqEntry; - VRKey vr; + //VRKey vr; bool used; // will be set to false when something wrong happens to an Entry. // (Entry will then be deleted) bool delim_mode_intern = delim_mode; bool first = true; gdcmDebugMacro( "Enter in ParseDES, delim-mode " << delim_mode - << " at offset " << std::hex << "0x(" << offset << ")" ); + << " at offset " << std::hex << "0x(" << offset << ")" ); while (true) { @@ -1063,29 +1065,30 @@ void Document::ParseDES(DocEntrySet *set, long offset, // Uncomment to track the bug /* if( Debug::GetDebugFlag() ) - std::cout << std::dec <<"(long)(Fp->tellg()) " << (long)(Fp->tellg()) + std::cout << std::dec <<"(long)(Fp->tellg()) " << (long)(Fp->tellg()) // in Debug mode << std::hex << " 0x(" <<(long)(Fp->tellg()) << ")" << std::endl; -*/ - + */ + // if ( !delim_mode && ((long)(Fp->tellg())-offset) >= l_max) // Once per DocEntry if ( !delim_mode ) // 'and then' doesn't exist in C++ :-( if ( ((long)(Fp->tellg())-offset) >= l_max) // Once per DocEntry, when no delim mode { break; } - newDocEntry = ReadNextDocEntry( ); - // Uncoment this cerr line to be able to 'follow' the DocEntries - // when something *very* strange happens - if( Debug::GetDebugFlag() ) - std::cerr<GetKey()<<" "<GetVR()<GetKey()<<" "<GetVR()<GetVR(); + //vr = newDocEntry->GetVR(); // useless ? if ( !set->AddEntry( newDataEntry ) ) { @@ -1232,7 +1235,6 @@ void Document::ParseDES(DocEntrySet *set, long offset, l, delim_mode_intern); gdcmDebugMacro( "Exit from ParseSQ, delim " << delim_mode_intern); - } if ( !set->AddEntry( newSeqEntry ) ) { @@ -1298,12 +1300,14 @@ void Document::ParseSQ( SeqEntry *seqEntry, break; } } - if ( !delim_mode ) // andthen doesn't exist in C++ :-( + else // ! delim_mode + { if ( ((long)(Fp->tellg())-offset) >= l_max) // Once per SQItem when no delim mode { newDocEntry->Delete(); break; } + } // create the current SQItem SQItem *itemSQ = SQItem::New( seqEntry->GetDepthLevel() ); unsigned int l = newDocEntry->GetReadLength(); @@ -1316,16 +1320,12 @@ void Document::ParseSQ( SeqEntry *seqEntry, { dlm_mod = false; } - - // remove fff0,e000, created out of the SQItem - - //Fp->seekg(offsetStartCurrentSQItem, std::ios::beg); //JPRx - + // fill up the current SQItem, starting at the beginning of fff0,e000 - + + Fp->seekg(offsetStartCurrentSQItem, std::ios::beg); // Once per SQItem ParseDES(itemSQ, offsetStartCurrentSQItem, l+8, dlm_mod); - - offsetStartCurrentSQItem = Fp->tellg(); // Once per SQItem + offsetStartCurrentSQItem = Fp->tellg(); // Once per SQItem seqEntry->AddSQItem( itemSQ, SQItemNumber ); itemSQ->Delete(); @@ -1381,10 +1381,10 @@ DocEntry *Document::Backtrack(DocEntry *docEntry) */ void Document::LoadDocEntry(DocEntry *entry, bool forceLoad) { - uint16_t group = entry->GetGroup(); - uint16_t elem = entry->GetElement(); + uint16_t group = entry->GetGroup(); + uint16_t elem = entry->GetElement(); const VRKey &vr = entry->GetVR(); - uint32_t length = entry->GetLength(); + uint32_t length = entry->GetLength(); // Fp->seekg((long)entry->GetOffset(), std::ios::beg); // JPRx @@ -1595,7 +1595,9 @@ uint32_t Document::FindDocEntryLengthOBOrOW() VRKey Document::FindDocEntryVR() { if ( Filetype != ExplicitVR ) + { return GDCM_VRUNKNOWN; + } // Delimiters (0xfffe), are not explicit VR ... if ( CurrentGroup == 0xfffe ) @@ -1622,7 +1624,7 @@ VRKey Document::FindDocEntryVR() if ( !CheckDocEntryVR(vr) ) { /* - std::cout << "================================================================Unknown VR" +// std::cout << "================================================================Unknown VR" << std::hex << "0x(" << (unsigned int)vr[0] << "|" << (unsigned int)vr[1] << ")" << "for : " << CurrentGroup @@ -1732,21 +1734,32 @@ void Document::FixDocEntryFoundLength(DocEntry *entry, // 'Leonardo' source. Hence, one might consider commenting out the // following fix on efficiency reasons. else if ( gr == 0x0009 && ( elem == 0x1113 || elem == 0x1114 ) ) - { - foundLength = 4; - entry->SetReadLength(4); // a bug is to be fixed ! - } - + { + // Ideally we should check we are in Explicit and double check + // that VR=UL... this is done properly in gdcm2 + if( foundLength == 6 ) + { + gdcmWarningMacro( "Replacing Length from 6 into 4" ); + foundLength = 4; + entry->SetReadLength(4); // a bug is to be fixed ! + } + else if ( foundLength%4 ) + { + gdcmErrorMacro( "This looks like to a buggy Siemens DICOM file." + "The length of this tag seems to be wrong" ); + } + } + else if ( entry->GetVR() == "SQ" ) { - foundLength = 0; // ReadLength is unchanged - } - - //////// We encountered a 'delimiter' element i.e. a tag of the form + foundLength = 0; // ReadLength is unchanged + } + + //////// 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 ( 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 // causes extra troubles... @@ -1758,7 +1771,7 @@ void Document::FixDocEntryFoundLength(DocEntry *entry, { foundLength=12; // to skip the mess that follows this bugged Tag ! } - } + } entry->SetLength(foundLength); } @@ -1794,6 +1807,7 @@ bool Document::IsDocEntryAnInteger(DocEntry *entry) // encounter such an ill-formed image, we simply display a warning // message and proceed on parsing (while crossing fingers). long filePosition = Fp->tellg(); // Only when elem 0x0000 length is not 4 (?!?) + (void)filePosition; gdcmWarningMacro( "Erroneous Group Length element length on : (" << std::hex << group << " , " << elem << ") -before- position x(" << filePosition << ")" @@ -2043,7 +2057,7 @@ void Document::SwitchByteSwapCode() * \brief during parsing, Header Elements too long are not loaded in memory * @param newSize new size */ -void Document::SetMaxSizeLoadEntry(long newSize) +void Document::SetMaxSizeLoadEntry(long newSize) { if ( newSize < 0 ) { @@ -2062,7 +2076,7 @@ void Document::SetMaxSizeLoadEntry(long newSize) * (read the 'Group Number', the 'Element Number', * gets the Dict Entry * gets the VR, gets the length, gets the offset value) - * @return On succes : the newly created DocEntry, NULL on failure. + * @return On succes : the newly created DocEntry, NULL on failure. */ DocEntry *Document::ReadNextDocEntry() { @@ -2073,7 +2087,7 @@ DocEntry *Document::ReadNextDocEntry() } catch ( FormatError ) { - // We reached the EOF (or an error occured) therefore + // We reached the EOF (or an error occured) therefore // header parsing has to be considered as finished. return 0; } @@ -2085,11 +2099,10 @@ DocEntry *Document::ReadNextDocEntry() HandleOutOfGroup0002(CurrentGroup, CurrentElem); else // Sometimes file contains groups of tags with reversed endianess. - HandleBrokenEndian(CurrentGroup, CurrentElem); + HandleBrokenEndian(CurrentGroup, CurrentElem); } - + VRKey vr = FindDocEntryVR(); - VRKey realVR = vr; if ( vr == GDCM_VRUNKNOWN ) @@ -2098,9 +2111,14 @@ DocEntry *Document::ReadNextDocEntry() { realVR = "UL"; // must be UL } + else if (CurrentGroup == 0xfffe) // Don't get DictEntry for Delimitors + { + realVR = "UL"; + } + // Commented out in order not to generate 'Shadow Groups' where some // Data Elements are Explicit VR and some other ones Implicit VR - // (Stupid MatLab DICOM Reader couln't read gdcm-written images) + // (Stupid MatLab DICOM Reader couldn't read gdcm-written images) /* else if (CurrentGroup%2 == 1 && (CurrentElem >= 0x0010 && CurrentElem <=0x00ff )) @@ -2112,11 +2130,11 @@ DocEntry *Document::ReadNextDocEntry() */ else { - DictEntry *dictEntry = GetDictEntry(CurrentGroup,CurrentElem); + DictEntry *dictEntry = GetDictEntry(CurrentGroup,CurrentElem);//only when ImplicitVR if ( dictEntry ) { realVR = dictEntry->GetVR(); - dictEntry->Unregister(); + dictEntry->Unregister(); // GetDictEntry registered it } } } @@ -2124,8 +2142,10 @@ DocEntry *Document::ReadNextDocEntry() DocEntry *newEntry; //if ( Global::GetVR()->IsVROfSequence(realVR) ) if (realVR == "SQ") + { newEntry = NewSeqEntry(CurrentGroup, CurrentElem); - else + } + else { newEntry = NewDataEntry(CurrentGroup, CurrentElem, realVR); static_cast(newEntry)->SetState(DataEntry::STATE_NOTLOADED); @@ -2137,14 +2157,14 @@ DocEntry *Document::ReadNextDocEntry() { // We thought this was explicit VR, but we end up with an // implicit VR tag. Let's backtrack. - if ( newEntry->GetGroup() != 0xfffe ) + + //if ( newEntry->GetGroup() != 0xfffe ) + if (CurrentGroup != 0xfffe ) { - std::string msg; int offset = Fp->tellg();//Only when heuristic for Explicit/Implicit was wrong - msg = Util::Format( - "Entry (%04x,%04x) at x(%x) should be Explicit VR\n", - newEntry->GetGroup(), newEntry->GetElement(), offset ); - gdcmWarningMacro( msg.c_str() ); + + gdcmWarningMacro("Entry (" << newEntry->GetKey() << ") at x(" + << offset << ") should be Explicit VR"); } } newEntry->SetImplicitVR();