Program: gdcm
Module: $RCSfile: gdcmDocument.cxx,v $
Language: C++
- Date: $Date: 2008/01/02 10:48:52 $
- Version: $Revision: 1.377 $
+ Date: $Date: 2008/01/04 13:32:01 $
+ Version: $Revision: 1.378 $
Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
l'Image). All rights reserved. See Doc/License.txt or
* @param l_max length to parse (meaningless when we are in 'delimitor mode')
* @param delim_mode : whether we are in 'delimitor mode' (l=0xffffff) or not
*/
-void Document::ParseDES(DocEntrySet *set, long offset,
+bool Document::ParseDES(DocEntrySet *set, long offset,
long l_max, bool delim_mode)
{
DocEntry *newDocEntry;
// (Entry will then be deleted)
bool delim_mode_intern = delim_mode;
bool first = true;
+ bool successParseDES = true;
gdcmDebugMacro( "Enter in ParseDES, delim-mode " << delim_mode
<< " at offset " << std::hex << "0x(" << offset << ")" );
while (true)
{
/////////////////////// SeqEntry : VR = "SQ"
- unsigned long l = newDocEntry->GetReadLength();
+ unsigned long l = newDocEntry->GetReadLength();
if ( l != 0 ) // don't mess the delim_mode for 'zero-length sequence'
{
if ( l == 0xffffffff )
{
newSeqEntry->SetDepthLevel( parentSQItem->GetDepthLevel() + 1 );
}
-
+
+ bool res = true;
if ( l != 0 )
{ // Don't try to parse zero-length sequences
<< " at offset 0x(" << std::hex
<< newDocEntry->GetOffset() << ")");
- bool res = ParseSQ( newSeqEntry,
+ res = ParseSQ( newSeqEntry,
newDocEntry->GetOffset(),
l, delim_mode_intern);
gdcmDebugMacro( "Exit from ParseSQ, delim " << delim_mode_intern << " -->return : " << res);
+
}
+
+ if ( !res )
+ {
+ gdcmDebugMacro( "in ParseDES : ParseSQ failed " << newSeqEntry->GetKey()
+ << " (at offset : 0x(" << std::hex
+ << newSeqEntry->GetOffset() << ") )" );
+
+ successParseDES = false;
+ newDocEntry = BacktrackSQtoOB(newSeqEntry, set);
+ set->AddEntry( newDocEntry); /// \todo fixme : the whole process is not done
+ /// (check SQItem length, when the DataElement is inside a Sequence)
+
+ //
+ //
+ //
+
+ continue;
+ }
+
if ( !set->AddEntry( newSeqEntry ) )
{
gdcmWarningMacro( "in ParseDES : cannot add a SeqEntry "
first = false;
if (UnexpectedEOF) // some terminator was missing
+ {
break;
+ }
} // end While
+
gdcmDebugMacro( "Exit from ParseDES, delim-mode " << delim_mode );
+
+ return successParseDES;
}
/**
if (offsetStartCurrentSQItem <= OffsetOfPreviousParseDES)
{
- gdcmWarningMacro("Bad assumption was made on illegal 'unknown length' UN!");
- gdcmWarningMacro("OffsetOfPreviousParseDES " << std::hex << OffsetOfPreviousParseDES
+ gdcmWarningMacro("Bad assumption was made on illegal 'unknown length' UN!" << std::endl <<
+ "OffsetOfPreviousParseDES " << std::hex << OffsetOfPreviousParseDES
<< " offsetStartCurrentSQItem " << offsetStartCurrentSQItem);
/// \todo when "Bad assumption (SQ) on illegal 'unknown length' UN", Backtrack again + try OB
return false;
// 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);
+ bool res = ParseDES(itemSQ, offsetStartCurrentSQItem, l+8, dlm_mod);
offsetStartCurrentSQItem = Fp->tellg(); // Once per SQItem
seqEntry->AddSQItem( itemSQ, SQItemNumber );
itemSQ->Delete();
newDocEntry->Delete();
SQItemNumber++;
+ if (!res) // to avoid extra -useless- work when illegal UN stands for OB ...
+ {
+ gdcmDebugMacro("in ParseSQ : ParseDES failed");
+ return false;
+ }
//if ( !delim_mode && ((long)(Fp->tellg())-offset ) >= l_max ) //JPRx
if ( !delim_mode && (offsetStartCurrentSQItem-offset ) >= l_max )
{
}
/**
- * \brief When a private Sequence + Implicit VR is encountered
+ * \brief When a private Sequence + Implicit VR
+ * (or UN + undefined length element) is encountered
* we cannot guess it's a Sequence till we find the first
* Item Starter. We then backtrack to do the job.
- * @param docEntry Item Starter that warned us
+ * @param docEntry Item Starter that warned us
+ * @param set DocEntrySet (ElementSet/SQItem) the DocEntry will belong
*/
DocEntry *Document::Backtrack(DocEntry *docEntry, DocEntrySet *set)
{
// Move back to the beginning of the Sequence
Fp->seekg(offset, std::ios::beg); // Only for Shadow Implicit VR SQ
- return newEntry; // It will added where it has to be!
+ return newEntry; // It will be added where it has to be!
+}
+
+
+/**
+ * \brief When a private OB + Implicit VR
+ * (or UN + undefined length element) is encountered
+ * we made first a bad assumption -it should be a Sequence-
+ * When we realize we were wrong, we backtrack.
+ * WARNING : it will probabely fail if the element
+ * is embedded within a sequence
+ * @param docEntry Item Starter that warned us
+ * @param set DocEntrySet (ElementSet/SQItem) the DocEntry will belong
+ */
+
+DataEntry *Document::BacktrackSQtoOB(SeqEntry *docEntry, DocEntrySet *set)
+{
+ // Get all info we can from SeqEntry
+
+ uint16_t group = docEntry->GetGroup();
+ uint16_t elem = docEntry->GetElement();
+ uint32_t lgt = docEntry->GetLength();
+ long offset = docEntry->GetOffset();
+
+ gdcmDebugMacro( "BacktrackSQtoOB(" << std::hex << group
+ << "|" << elem
+ << " at offset 0x(" <<offset << ")" );
+
+ //set->RemoveEntry( docEntry );
+ docEntry->Delete(); // not yet included into a DocEntrySet !
+
+ // forge the OB Entry
+ DataEntry *newEntry = NewDataEntry(group, elem, "OB");
+ newEntry->SetOffset(offset);
+
+ // Move back to the beginning of the Element
+ Fp->seekg(offset, std::ios::beg);
+
+ uint32_t lengthOB = FindDocEntryLengthOBOrOW();// for encapsulation of encoded pixel
+
+ newEntry->SetReadLength(lengthOB);
+ newEntry->SetLength(lengthOB);
+
+ Fp->seekg(offset, std::ios::beg);
+ LoadDocEntry(newEntry, true); // true : forceload
+
+ /// \todo fixme : it will fail if the element
+ /// is embedded within a sequence (sequence length checking is not done)
+
+ return newEntry; // It will be added (ElementSet/SQItem) where it has to be!
}
/**
{
gdcmWarningMacro(
"Neither an Item tag nor a Sequence delimiter tag on :"
- << std::hex << group << " , " << elem
- << ")" );
+ << std::hex << group << "|" << elem << ") Pos. on entry was 0x(" <<positionOnEntry<< ") "
+ );
Fp->seekg(positionOnEntry, std::ios::beg); // Once per fragment (if any) of OB,OW DataElements
throw FormatUnexpected(
if ( !Global::GetVR()->IsValidVR(vr) )
{
- gdcmWarningMacro( "Unknown VR " << vr.GetHexaRepresentation()
+ gdcmWarningMacro( "Unknown VR " << vr.GetHexaRepresentation() << std::hex
<< " at offset : 0x(" << CurrentOffsetPosition-4
<< ") for group " << std::hex << CurrentGroup );
Program: gdcm
Module: $RCSfile: gdcmDocument.h,v $
Language: C++
- Date: $Date: 2008/01/02 10:48:52 $
- Version: $Revision: 1.150 $
+ Date: $Date: 2008/01/04 13:32:01 $
+ Version: $Revision: 1.151 $
Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
l'Image). All rights reserved. See Doc/License.txt or
uint32_t UnswapLong(uint32_t a) { return SwapLong(a);}
// Read
- void ParseDES(DocEntrySet *set, long offset, long l_max, bool delim_mode);
+ bool ParseDES(DocEntrySet *set, long offset, long l_max, bool delim_mode);
bool ParseSQ (SeqEntry *seq, long offset, long l_max, bool delim_mode);
void LoadDocEntry (DocEntry *e, bool forceLoad = false);
void HandleBrokenEndian (uint16_t &group, uint16_t &elem);
void HandleOutOfGroup0002(uint16_t &group, uint16_t &elem);
- DocEntry *Backtrack(DocEntry *docEntry, DocEntrySet *set);
-
-// Variables
+ DocEntry *Backtrack(DocEntry *docEntry, DocEntrySet *set);
+ DataEntry *BacktrackSQtoOB(SeqEntry *docEntry, DocEntrySet *set);
protected:
/// value of the ??? for any progress bar
float Progress;