]> Creatis software - gdcm.git/commitdiff
Illegal 'undefined length UN DataElement' :
authorjpr <jpr>
Wed, 2 Jan 2008 10:48:52 +0000 (10:48 +0000)
committerjpr <jpr>
Wed, 2 Jan 2008 10:48:52 +0000 (10:48 +0000)
when UN stands for SQ : now we can read them correctly.
when UN stands for OB : no more infinite loop.
                       (a clever backtrack is still missing ...)

src/gdcmDocument.cxx
src/gdcmDocument.h
src/gdcmJPEGFragment.cxx
src/gdcmVRKey.h

index bd497da659500399d7fe77450548d686606f53b2..efe6d1c92f85856307ad1b4667a63b8a34699a3b 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmDocument.cxx,v $
   Language:  C++
-  Date:      $Date: 2007/12/05 16:36:21 $
-  Version:   $Revision: 1.376 $
+  Date:      $Date: 2008/01/02 10:48:52 $
+  Version:   $Revision: 1.377 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -63,6 +63,7 @@ Document::Document()
    SwapCode = 1234;
    Filetype = ExplicitVR;
    CurrentOffsetPosition = 0;
+   OffsetOfPreviousParseDES =0;
    // Load will set it to true if sucessfull
    Group0002Parsed = false;
    IsDocumentAlreadyLoaded = false;
@@ -161,6 +162,7 @@ bool Document::DoTheLoadingDocumentJob(  )
 
    // Recursive call.
    // Loading is done during parsing
+   OffsetOfPreviousParseDES = beg; 
    ParseDES( this, beg, lgt, false); // delim_mode is first defaulted to false
 
    if ( IsEmpty() )
@@ -1117,14 +1119,14 @@ void Document::ParseDES(DocEntrySet *set, long offset,
    {
    
    ///\todo FIXME : On 64 bits processors, tellg gives unexpected results after a while ?
-   ///              Probabely a bug in gdcm code somwhere (some memory erased ?)
+   ///              Probabely a bug in gdcm code somewhere (some memory erased ?)
 
 // Uncomment to track the bug
-/*   
+  
    if( Debug::GetDebugFlag() )   
       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++ :-(
@@ -1152,7 +1154,7 @@ void Document::ParseDES(DocEntrySet *set, long offset,
       if ( !first && newDocEntry->IsItemStarter() )
       {
          // Debug message within the method !
-         newDocEntry = Backtrack(newDocEntry);
+         newDocEntry = Backtrack(newDocEntry, set);
       }
       else
       { 
@@ -1383,8 +1385,23 @@ bool Document::ParseSQ( SeqEntry *seqEntry,
          dlm_mod = false;
       }
             
+      // avoid infinite loop when Bad assumption was made on illegal 'unknown length' UN //JPRx
+    
+      if (offsetStartCurrentSQItem <= OffsetOfPreviousParseDES)
+      {
+         gdcmWarningMacro("Bad assumption was made on illegal 'unknown length' UN!");
+         gdcmWarningMacro("OffsetOfPreviousParseDES " << std::hex << OffsetOfPreviousParseDES
+                           << " offsetStartCurrentSQItem " << offsetStartCurrentSQItem);
+         /// \todo when  "Bad assumption (SQ) on illegal 'unknown length' UN", Backtrack again + try OB      
+         return false; 
+      }
+      else 
+      {
+         OffsetOfPreviousParseDES = offsetStartCurrentSQItem;
+      }
+     
       // 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
@@ -1408,7 +1425,7 @@ bool Document::ParseSQ( SeqEntry *seqEntry,
  *           Item Starter. We then backtrack to do the job.
  * @param   docEntry Item Starter that warned us 
  */
-DocEntry *Document::Backtrack(DocEntry *docEntry)
+DocEntry *Document::Backtrack(DocEntry *docEntry, DocEntrySet *set)
 {
    // delete the Item Starter, built erroneously out of any Sequence
    // it's not yet in the HTable/chained list
@@ -1423,7 +1440,8 @@ DocEntry *Document::Backtrack(DocEntry *docEntry)
    gdcmDebugMacro( "Backtrack :" << std::hex << group 
                                  << "|" << elem
                                  << " at offset 0x(" <<offset << ")" );
-   RemoveEntry( PreviousDocEntry );
+   
+   set->RemoveEntry( PreviousDocEntry );
 
    // forge the Seq Entry
    DocEntry *newEntry = NewSeqEntry(group, elem);
@@ -1433,7 +1451,7 @@ DocEntry *Document::Backtrack(DocEntry *docEntry)
    // Move back to the beginning of the Sequence
 
    Fp->seekg(offset, std::ios::beg); // Only for Shadow Implicit VR SQ
-   return newEntry;
+   return newEntry; // It will added where it has to be!
 }
 
 /**
@@ -1704,21 +1722,12 @@ VRKey Document::FindDocEntryVR()
    
    //if ( !CheckDocEntryVR(vr) ) // avoid useless function call
    if ( !Global::GetVR()->IsValidVR(vr) )
-   {
-/*   
-//      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(" << CurrentOffsetPosition-4<< ") for group " << CurrentGroup
-                        );
+   {  
 
+      gdcmWarningMacro( "Unknown VR " << vr.GetHexaRepresentation() 
+                        << " at offset : 0x(" << CurrentOffsetPosition-4
+                        << ") for group " << std::hex << CurrentGroup );
+                        
       //Fp->seekg(positionOnEntry, std::ios::beg); //JPRx
       //Fp->seekg((long)-2, std::ios::cur);// only for unrecognized VR (?!?) 
                                          //see :MR_Philips_Intera_PrivateSequenceExplicitVR.dcm
@@ -1792,10 +1801,12 @@ void Document::FixDocEntryFoundLength(DocEntry *entry,
      
    if ( foundLength % 2)
    {
-      gdcmWarningMacro( "Warning : Tag with uneven length " << foundLength
-        <<  " in x(" << std::hex << gr << "," << elem <<")");
+      gdcmWarningMacro( "Warning : Tag (" << std::hex << gr << "|" << elem << ") with uneven length " 
+        << std::dec << foundLength << " 0x(" << std::hex << foundLength << ") "
+        //<< " at offset x(" << offset << ")"
+       );
    }
-      
+
    //////// Fix for some naughty General Electric images.
    // Allthough not recent many such GE corrupted images are still present
    // on Creatis hard disks. Hence this fix shall remain when such images
@@ -2270,7 +2281,7 @@ DocEntry *Document::ReadNextDocEntry()
          }
          else if ( CurrentElem == 0x0001)
          {
-            realVR = "UL"; // Private Group Length To Eng
+            realVR = "UL"; // Private Group Length To End
          }
          else  // check the private dictionary for shadow elements when Implicit VR!
          {
@@ -2341,7 +2352,7 @@ DocEntry *Document::ReadNextDocEntry()
             int offset = Fp->tellg();//Only when heuristic for Explicit/Implicit was wrong
 
             gdcmWarningMacro("Entry (" << newEntry->GetKey() << ") at x("
-                     <<  offset << ") should be Explicit VR");
+                     <<  std::hex << offset << ") should be Explicit VR");
           }
       }
       newEntry->SetImplicitVR();
index fb55b8a640695a201b8761c118a7219ce004322e..ef3978c9fbbb91fa1e81ba4ef13eff73b1ed76cd 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmDocument.h,v $
   Language:  C++
-  Date:      $Date: 2007/12/03 11:47:40 $
-  Version:   $Revision: 1.149 $
+  Date:      $Date: 2008/01/02 10:48:52 $
+  Version:   $Revision: 1.150 $
  
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -225,7 +225,7 @@ private:
 
    void HandleBrokenEndian  (uint16_t &group, uint16_t &elem);
    void HandleOutOfGroup0002(uint16_t &group, uint16_t &elem);
-   DocEntry *Backtrack(DocEntry *docEntry);
+   DocEntry *Backtrack(DocEntry *docEntry, DocEntrySet *set);
 
 // Variables
 protected:
@@ -265,6 +265,8 @@ private:
    bool changeFromUN;
    /// \brief whether an unexpected EOF was encountered
    bool UnexpectedEOF;
+   /// \brief to avoid infinite loop when illegal UN stands for OB
+   size_t OffsetOfPreviousParseDES;
 };
 
 } // end namespace gdcm
index 02b7a071aacbe522f85899291ed3b3d86978ca1b..3a50c996bbceac1474a271afba6cc4c04b95a17d 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmJPEGFragment.cxx,v $
   Language:  C++
-  Date:      $Date: 2007/08/22 16:14:04 $
-  Version:   $Revision: 1.19 $
+  Date:      $Date: 2008/01/02 10:48:52 $
+  Version:   $Revision: 1.20 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -104,8 +104,10 @@ void JPEGFragment::DecompressJPEGFramesFromFile(std::ifstream *fp,
 void JPEGFragment::Print( std::ostream &os, std::string const &indent )
 {
    os << indent
-      << "JPEG fragment: offset : " <<  Offset
-      << "   length : " <<  Length
+      << "JPEG fragment: offset : " <<  std::dec << Offset 
+      << " 0x(" << std::hex << Offset << ") "
+      << std::dec << "   length : " <<  Length
+      << " 0x(" << std::hex << Length << ") "      
       << std::endl;
 }
 
index 2ef89e2aee6aae351d97048ef824fb22d78cc983..c192735bf6ee0ab561fbbd277cb16e1429f9b178 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmVRKey.h,v $
   Language:  C++
-  Date:      $Date: 2007/08/22 16:14:05 $
-  Version:   $Revision: 1.8 $
+  Date:      $Date: 2008/01/02 10:48:52 $
+  Version:   $Revision: 1.9 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -107,6 +107,23 @@ public :
       return key[0] < _val[0] || (key[0] == _val[0] && key[1] < _val[1]);
    }
 
+   inline std::string GetHexaRepresentation()
+   {
+     // We could probabelly write something much more complicated using C++ features !
+     // (I really want HexaRepresentation as xx|xx, not ffffffxx|ffffffxx !)
+      char vr_char[6];
+      char buf[5];
+      sprintf(buf, "%04x",( unsigned short int)key[0]);
+      vr_char[0] = buf[2];
+      vr_char[1] = buf[3];      
+      sprintf(buf, "%04x",( unsigned short int)key[1]);
+      vr_char[2] = '|';
+      vr_char[3] = buf[2];            
+      vr_char[4] = buf[3];
+      vr_char[5] = '\0';
+      return(vr_char);
+   }
+   
 private :
    char key[2];
 };