Program: gdcm
Module: $RCSfile: gdcmDocument.cxx,v $
Language: C++
- Date: $Date: 2006/02/07 17:15:28 $
- Version: $Revision: 1.339 $
+ Date: $Date: 2006/02/08 17:34:47 $
+ Version: $Revision: 1.340 $
Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
l'Image). All rights reserved. See Doc/License.txt or
gdcmDebugMacro( "Starting parsing of file: " << Filename.c_str());
// Computes the total length of the file
- Fp->seekg(0, std::ios::end); // Once for a given Document !
- long lgt = Fp->tellg(); // Once for a given Document !
- Fp->seekg(0, std::ios::beg); // Once for a given Document !
+ Fp->seekg(0, std::ios::end); // Once per Document !
+ long lgt = Fp->tellg(); // Once per Document !
+ Fp->seekg(0, std::ios::beg); // Once per Document !
// CheckSwap returns a boolean
// (false if no swap info of any kind was found)
}
//-- DICOM --
- Fp->seekg(126L, std::ios::cur); // Once for a given Document
+ Fp->seekg(126L, std::ios::cur); // Once per Document
char dicm[4]; // = {' ',' ',' ',' '};
Fp->read(dicm, (size_t)4);
if ( Fp->eof() )
<< " at offset " << std::hex << "0x(" << offset << ")" );
while (true)
{
- if ( !delim_mode && ((long)(Fp->tellg())-offset) >= l_max) // Once per DocEntry
- {
- break;
- }
-
+ // 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
if ( !set->AddEntry( newDataEntry ) )
{
gdcmDebugMacro( "in ParseDES : cannot add a DataEntry "
- << newDataEntry->GetKey()
+ << newDataEntry->GetKey()
<< " (at offset : 0x("
<< newDataEntry->GetOffset() << ") )" );
used=false;
}
}
- bool delimitor = newDataEntry->IsItemDelimitor();
+ bool delimitor = newDataEntry->IsItemDelimitor();
+ bool outOfBounds = false;
+ if (!delim_mode )
+ if ( ((long)(Fp->tellg())-offset) >= l_max ) //Once per DataEntry when no delim mode
+ outOfBounds = true;
+
+ // 'and then', 'or else' don't exist in C++ :-(
+ // if ( (delimitor) ||
+ // (!delim_mode && ((long)(Fp->tellg())-offset) >= l_max) ) // Once per DataEntry
- if ( (delimitor) ||
- (!delim_mode && ((long)(Fp->tellg())-offset) >= l_max) ) // Once per DataEntry
+ if ( delimitor || outOfBounds )
{
if ( !used )
newDocEntry->Delete();
}
// Just to make sure we are at the beginning of next entry.
- SkipToNextDocEntry(newDocEntry); // FIXME : once per DocEntry, segfault if commented out
+ SkipToNextDocEntry(newDocEntry); // FIXME : once per DocEntry, segfault if commented out
}
else
{
{
newDocEntry->Delete();
}
+
+ // if ( !delim_mode && ((long)(Fp->tellg())-offset) >= l_max) // Once per SeqEntry
- if ( !delim_mode && ((long)(Fp->tellg())-offset) >= l_max) // Once per SeqEntry
+ if ( !delim_mode ) // andthen doesn't exist in C++ :-(
+ if ( ((long)(Fp->tellg())-offset) >= l_max) // Once per SeqEntry when no delim mode
+
{
if ( !used )
newDocEntry->Delete();
break;
}
}
- if ( !delim_mode && ((long)(Fp->tellg())-offset) >= l_max) // Once per SQItem
- {
- newDocEntry->Delete();
- break;
- }
+ if ( !delim_mode ) // andthen doesn't exist in C++ :-(
+ 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();
//<< ") -before- position x(" << filePosition // JPRx
<< ")" );
- Fp->seekg(positionOnEntry, std::ios::beg); // Oncd per fragment (if any) of OB,OW DataElements
+ Fp->seekg(positionOnEntry, std::ios::beg); // Once per fragment (if any) of OB,OW DataElements
throw FormatUnexpected(
"Neither an Item tag nor a Sequence delimiter tag.");
}
if ( Filetype != ExplicitVR )
return GDCM_VRUNKNOWN;
- //long positionOnEntry = Fp->tellg(); // JPRx
+ // Delimiters (0xfffe), are not explicit VR ...
+ if ( CurrentGroup == 0xfffe )
+ return GDCM_VRUNKNOWN;
+
+ long positionOnEntry;
+ if( Debug::GetWarningFlag() )
+ positionOnEntry = Fp->tellg(); // Only in Warning Mode
// Warning: we believe this is explicit VR (Value Representation) because
// we used a heuristic that found "UL" in the first tag and/or
if ( !CheckDocEntryVR(vr) )
{
- // Don't warn user with useless messages
- // Often, delimiters (0xfffe), are not explicit VR ...
- if ( CurrentGroup != 0xfffe )
- gdcmWarningMacro( "Unknown VR " << std::hex << "0x("
+/*
+ std::cout << "================================================================Unknown VR"
+ << std::hex << "0x("
+ << (unsigned int)vr[0] << "|" << (unsigned int)vr[1]
+ << ")" << "for : " << CurrentGroup
+ << " at offset : 0x(" << positionOnEntry << ")"
+ << std::endl;
+*/
+ gdcmWarningMacro( "Unknown VR " << std::hex << "0x("
<< (unsigned int)vr[0] << "|" << (unsigned int)vr[1]
<< ")"
- //<< "at offset : 0x(" << positionOnEntry<< ")"
+ << " at offset : 0x(" << positionOnEntry<< ") for group " << CurrentGroup
);
//Fp->seekg(positionOnEntry, std::ios::beg); //JPRx
- Fp->seekg((long)-2, std::ios::cur);// FIXME : for each VR !
+ Fp->seekg((long)-2, std::ios::cur);// only for unrecognized VR (?!?)
+ //see :MR_Philips_Intera_PrivateSequenceExplicitVR.dcm
return GDCM_VRUNKNOWN;
}
return vr;
Fp->seekg((long)(currentDocEntry->GetOffset()), std::ios::beg); //FIXME :each DocEntry
if (currentDocEntry->GetGroup() != 0xfffe) // for fffe pb
{
- //Fp->seekg( (long)(currentDocEntry->GetReadLength()),std::ios::cur);
- Fp->seekg( l,std::ios::cur); //FIXME :each DocEntry
+ Fp->seekg( l,std::ios::cur); //FIXME :each DocEntry
}
}
memcmp(entCur, "AE", (size_t)2) == 0 ||
memcmp(entCur, "OB", (size_t)2) == 0 )
{
- Filetype = ExplicitVR;
+ Filetype = ExplicitVR; // FIXME : not enough to say it's Explicit
+ // Wait untill reading Transfer Syntax
gdcmDebugMacro( "Group 0002 : Explicit Value Representation");
return true;
}
return 0;
}
- // Sometimes file contains groups of tags with reversed endianess.
- HandleBrokenEndian(CurrentGroup, CurrentElem);
-
// In 'true DICOM' files Group 0002 is always little endian
- if ( HasDCMPreamble )
- HandleOutOfGroup0002(CurrentGroup, CurrentElem);
-
+ if ( HasDCMPreamble )
+ {
+ if ( !Group0002Parsed && CurrentGroup != 0x0002) // avoid calling a function when useless
+ HandleOutOfGroup0002(CurrentGroup, CurrentElem);
+ else
+ // Sometimes file contains groups of tags with reversed endianess.
+ HandleBrokenEndian(CurrentGroup, CurrentElem);
+ }
+
VRKey vr = FindDocEntryVR();
VRKey realVR = vr;
}
}
}
- // gdcmDebugMacro( "Found VR: " << vr << " / Real VR: " << realVR );
-
+
DocEntry *newEntry;
- if ( Global::GetVR()->IsVROfSequence(realVR) )
+ //if ( Global::GetVR()->IsVROfSequence(realVR) )
+ if (realVR == "SQ")
newEntry = NewSeqEntry(CurrentGroup, CurrentElem);
else
{
if ( newEntry->GetGroup() != 0xfffe )
{
std::string msg;
- int offset = Fp->tellg(); // FIXME : Only when heuristic for Explicit/Implicit was wrong
+ 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 );
{
// Endian reversion.
// Some files contain groups of tags with reversed endianess.
- if ( !Group0002Parsed && group != 0x0002)
- {
+
Group0002Parsed = true;
// we just came out of group 0002
// if Transfer Syntax is Big Endian we have to change CheckSwap
std::string ts = GetTransferSyntax();
+ TS::SpecialType s = Global::GetTS()->GetSpecialTransferSyntax(ts);
// Group 0002 is always 'Explicit ...'
// even when Transfer Syntax says 'Implicit ..."
- if ( Global::GetTS()->GetSpecialTransferSyntax(ts) ==
- TS::ImplicitVRLittleEndian )
+ if ( s == TS::ImplicitVRLittleEndian
+ ||
+ s == TS::ImplicitVRBigEndianPrivateGE
+ )
{
Filetype = ImplicitVR;
}
// to trust manufacturers.
// (we find very often 'Implicit VR' tag,
// even when Transfer Syntax tells us it's Explicit ...
- if ( Global::GetTS()->GetSpecialTransferSyntax(ts) ==
- TS::ExplicitVRBigEndian )
+
+ if ( s == TS::ExplicitVRBigEndian )
{
gdcmDebugMacro("Transfer Syntax Name = ["
<< GetTransferSyntaxName() << "]" );
/// \todo find a trick to warn user and stop processing
- if ( Global::GetTS()->GetSpecialTransferSyntax(ts) ==
- TS::DeflatedExplicitVRLittleEndian)
+ if ( s == TS::DeflatedExplicitVRLittleEndian)
{
gdcmWarningMacro("Transfer Syntax ["
<< GetTransferSyntaxName() << "] :"
<< ts << "]");
return;
}
- }
}
//-----------------------------------------------------------------------------