]> Creatis software - gdcm.git/blobdiff - src/gdcmDocument.cxx
comment out deprecated method Load(filename), everywhere.
[gdcm.git] / src / gdcmDocument.cxx
index 5f6d117066a1b0b01e0bc889ccc336bcad3df691..1a3f177c3525696ae6a6126d146b0625c3f84943 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmDocument.cxx,v $
   Language:  C++
-  Date:      $Date: 2005/10/26 06:34:03 $
-  Version:   $Revision: 1.309 $
+  Date:      $Date: 2005/11/21 16:28:06 $
+  Version:   $Revision: 1.331 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -76,7 +76,6 @@ Document::~Document ()
 
 //-----------------------------------------------------------------------------
 // Public
-
 /**
  * \brief   Loader. use SetLoadMode(), SetFileName() before ! 
  * @return false if file cannot be open or no swap info was found,
@@ -90,18 +89,17 @@ bool Document::Load(  )
       return false;
    }
    return DoTheLoadingDocumentJob( );
-} 
-/**
- * \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.
- */
+}
+
+/*
+//#ifndef GDCM_LEGACY_REMOVE 
 bool Document::Load( std::string const &fileName ) 
 {
    Filename = fileName;
    return DoTheLoadingDocumentJob( );
 }
+//#endif
+*/
 
 /**
  * \brief   Performs the Loading Job (internal use only)  
@@ -119,8 +117,6 @@ bool Document::DoTheLoadingDocumentJob(  )
    if ( !OpenFile() )
    {
       // warning already performed in OpenFile()
-      //gdcmWarningMacro( "Unable to open as an ACR/DICOM file: "
-      //                 << Filename.c_str() );
       Filetype = Unknown;
       return false;
    }
@@ -154,7 +150,7 @@ bool Document::DoTheLoadingDocumentJob(  )
 
    if ( IsEmpty() )
    { 
-      gdcmWarningMacro( "No tag in internal hash table for: "
+      gdcmErrorMacro( "No tag in internal hash table for: "
                         << Filename.c_str());
       CloseFile(); 
       return false;
@@ -174,20 +170,33 @@ bool Document::DoTheLoadingDocumentJob(  )
       LoadEntryBinArea(0x0028,0x1200);  // gray LUT
    
       /// FIXME
+      /// --> FIXME : The difference between BinEntry and DataEntry
+      /// --> no longer exists, but the alteration of Dicom Dictionary remains.
+      /// --> Old comment restored on purpose.
+      /// --> New one (replacing both BinEntry and ValEntry by DataEntry)
+      /// --> had absolutely no meaning.
+      /// --> The whole comment will be removed when the stuff is cleaned !
+      /// -->
       /// The tags refered by the three following lines used to be CORRECTLY
       /// defined as having an US Value Representation in the public
       /// dictionary. BUT the semantics implied by the three following
       /// lines state that the corresponding tag contents are in fact
-      /// the ones of a DataEntry.
+      /// the ones of a BinEntry.
       /// In order to fix things "Quick and Dirty" the dictionary was
       /// altered on PURPOSE but now contains a WRONG value.
       /// In order to fix things and restore the dictionary to its
-      /// correct value, one needs to decided of the semantics by deciding
+      /// correct value, one needs to decide of the semantics by deciding
       /// whether the following tags are either :
-      /// - multivaluated US, and hence loaded as DataEntry, but afterwards
-      ///   also used as DataEntry, which requires the proper conversion,
-      /// - OW, and hence loaded as DataEntry, but afterwards also used
-      ///   as DataEntry, which requires the proper conversion.
+      /// - multivaluated US, and hence loaded as ValEntry, but afterwards
+      ///   also used as BinEntry, which requires the proper conversion,
+      /// - OW, and hence loaded as BinEntry, but afterwards also used
+      ///   as ValEntry, which requires the proper conversion.
+      
+      // --> OB (byte aray) or OW (short int aray)
+      // The actual VR has to be deduced from other entries.
+      // Our way of loading them may fail in some cases :
+      // We must or not SwapByte depending on other field values.
+             
       LoadEntryBinArea(0x0028,0x1201);  // R    LUT
       LoadEntryBinArea(0x0028,0x1202);  // G    LUT
       LoadEntryBinArea(0x0028,0x1203);  // B    LUT
@@ -212,6 +221,8 @@ bool Document::DoTheLoadingDocumentJob(  )
          {
             if ( dataEntry->GetLength() != 0 )
             {
+               // FIXME : CTX dependent means : contexted dependant.
+               //         see upper comment.
                LoadEntryBinArea(dataEntry);    //LUT Data (CTX dependent)
             }   
         }
@@ -225,7 +236,7 @@ bool Document::DoTheLoadingDocumentJob(  )
                                it != UserForceLoadList.end();
                              ++it)
    {
-      gdcmWarningMacro( "Force Load " << std::hex 
+      gdcmDebugMacro( "Force Load " << std::hex 
                        << (*it).Group << "|" <<(*it).Elem );
   
       d = GetDocEntry( (*it).Group, (*it).Elem);
@@ -325,11 +336,11 @@ bool Document::SetShaDict(DictKey const &dictName)
  * @return false when we're 150 % sure it's NOT a Dicom/Acr file,
  *         true otherwise. 
  */
-bool Document::IsReadable()
+bool Document::IsParsable()
 {
    if ( Filetype == Unknown )
    {
-      gdcmWarningMacro( "Wrong filetype");
+      gdcmWarningMacro( "Wrong filetype for " << GetFileName());
       return false;
    }
 
@@ -341,6 +352,17 @@ bool Document::IsReadable()
 
    return true;
 }
+/**
+ * \brief  This predicate tells us whether or not the current Document 
+ *         was properly parsed and contains at least *one* Dicom Element
+ *         (and nothing more, sorry).
+ * @return false when we're 150 % sure it's NOT a Dicom/Acr file,
+ *         true otherwise. 
+ */
+bool Document::IsReadable()
+{
+   return IsParsable();
+}
 
 /**
  * \brief   Predicate for dicom version 3 file.
@@ -409,6 +431,7 @@ std::string Document::GetTransferSyntax()
       if  ( transfer.length() == 0 )
       {
          // for brain damaged headers
+         gdcmWarningMacro( "Transfer Syntax has length = 0.");
          return GDCM_UNKNOWN;
       }
       while ( !isdigit((unsigned char)transfer[transfer.length()-1]) )
@@ -417,6 +440,7 @@ std::string Document::GetTransferSyntax()
          if  ( transfer.length() == 0 )
          {
             // for brain damaged headers
+            gdcmWarningMacro( "Transfer Syntax contains no valid character.");
             return GDCM_UNKNOWN;
          }
       }
@@ -442,7 +466,7 @@ std::string Document::GetTransferSyntaxName()
    }
    if ( transferSyntax == GDCM_UNFOUND )
    {
-      gdcmWarningMacro( "Unfound Transfer Syntax (0002,0010)");
+      gdcmDebugMacro( "Unfound Transfer Syntax (0002,0010)");
       return "Uncompressed ACR-NEMA";
    }
 
@@ -495,12 +519,48 @@ uint32_t Document::SwapLong(uint32_t a)
          a=( ((a<< 8) & 0xff00ff00) | ((a>>8) & 0x00ff00ff)  );
       break;
       default :
-         gdcmErrorMacro( "Unset swap code:" << SwapCode );
+         gdcmErrorMacro( "Unexpected swap code:" << SwapCode );
          a = 0;
    }
    return a;
 } 
 
+/**
+ * \brief   Swaps back the bytes of 8-byte long 'double' accordingly to
+ *          processor order.
+ * @return  The properly swaped 64 bits double.
+ */
+double Document::SwapDouble(double a)
+{
+   switch (SwapCode)
+   {
+      // There were no 'double' at ACR-NEMA time.
+      // We just have to deal with 'straight Little Endian' and 
+      // 'straight Big Endian'
+      case 1234 :
+         break;
+      case 4321 :
+         {
+         char *beg = (char *)&a;
+         char *end = beg + 7;
+         char t;
+         for (unsigned int i = 0; i<7; i++)
+         {
+            t    = *beg;
+            *beg = *end;
+            *end = t;
+            beg++,
+            end--;  
+         }
+         }
+         break;   
+      default :
+         gdcmErrorMacro( "Unexpected swap code:" << SwapCode );
+         a = 0.;
+   }
+   return a;
+} 
+
 //
 // -----------------File I/O ---------------
 /**
@@ -518,7 +578,7 @@ std::ifstream *Document::OpenFile()
 
    if ( Fp )
    {
-      gdcmWarningMacro( "File already open: " << Filename.c_str());
+      gdcmDebugMacro( "File already open: " << Filename.c_str());
       CloseFile();
    }
 
@@ -529,6 +589,10 @@ std::ifstream *Document::OpenFile()
    // a spurious message will appear when you use, for instance 
    // gdcm::FileHelper *fh = new gdcm::FileHelper( outputFileName );
    // to create outputFileName.
+   
+   // FIXME : if the upper comment is still usefull 
+   //         --> the constructor is not so good ...
+   
       gdcmWarningMacro( "Cannot open file: " << Filename.c_str());
       delete Fp;
       Fp = 0;
@@ -545,7 +609,10 @@ std::ifstream *Document::OpenFile()
       return 0;
    }
  
-   //-- ACR or DICOM with no Preamble; may start with a Shadow Group --
+   //-- Broken ACR or DICOM with no Preamble; may start with a Shadow Group --
+   
+   // FIXME : We cannot be sure the preable is only zeroes..
+   //         (see ACUSON-24-YBR_FULL-RLE.dcm )
    if ( 
        zero == 0x0001 || zero == 0x0100 || zero == 0x0002 || zero == 0x0200 ||
        zero == 0x0003 || zero == 0x0300 || zero == 0x0004 || zero == 0x0400 ||
@@ -553,7 +620,8 @@ std::ifstream *Document::OpenFile()
        zero == 0x0007 || zero == 0x0700 || zero == 0x0008 || zero == 0x0800 )
    {
       std::string msg = Util::Format(
-        "ACR/DICOM starting at the beginning of the file:(%04x)\n", zero);
+        "ACR/DICOM starting by 0x(%04x) at the beginning of the file\n", zero);
+      // FIXME : is it a Warning message, or a Debug message?
       gdcmWarningMacro( msg.c_str() );
       return Fp;
    }
@@ -575,7 +643,9 @@ std::ifstream *Document::OpenFile()
 
    // -- Neither ACR/No Preamble Dicom nor DICOMV3 file
    CloseFile();
-   gdcmWarningMacro( "Neither ACR/No Preamble Dicom nor DICOMV3 file: "
+   // Don't user Warning nor Error, not to polute the output
+   // while directory recursive parsing ...
+   gdcmDebugMacro( "Neither ACR/No Preamble Dicom nor DICOMV3 file: "
                       << Filename.c_str()); 
    return 0;
 }
@@ -625,6 +695,10 @@ void Document::WriteContent(std::ofstream *fp, FileType filetype)
     *    UpdateGroupLength(false,filetype);
     * if ( filetype == ACR)
     *    UpdateGroupLength(true,ACR);
+    *
+    * --> Computing group length for groups with embeded Sequences
+    * --> was too much tricky / we were [in a hurry / too lazy]
+    * --> We don't write the element 0x0000 (group length)
     */
 
    ElementSet::WriteContent(fp, filetype); // This one is recursive
@@ -644,15 +718,15 @@ void Document::LoadEntryBinArea(uint16_t group, uint16_t elem)
    DocEntry *docEntry = GetDocEntry(group, elem);
    if ( !docEntry )
    {
-      gdcmWarningMacro(std::hex << group << "|" << elem 
-                       <<  "doesn't exist" );
+      gdcmDebugMacro(std::hex << group << "|" << elem 
+                       <<  " doesn't exist" );
       return;
    }
    DataEntry *dataEntry = dynamic_cast<DataEntry *>(docEntry);
    if ( !dataEntry )
    {
       gdcmWarningMacro(std::hex << group << "|" << elem 
-                       <<  "is NOT a DataEntry");
+                       <<  " is NOT a DataEntry");
       return;
    }
    LoadEntryBinArea(dataEntry);
@@ -698,11 +772,17 @@ void Document::LoadEntryBinArea(DataEntry *entry)
    uint32_t i;
    unsigned short vrLgth = 
                         Global::GetVR()->GetAtomicElementLength(entry->GetVR());
-   if( entry->GetVR() == "OW" )
-      vrLgth = 1;
+
+// FIXME : trouble expected if we read an ... OW Entry (LUT, etc ..)
+//   if( entry->GetVR() == "OW" )
+//      vrLgth = 1;
 
    switch(vrLgth)
    {
+      case 1:
+      {
+         break;
+      }     
       case 2:
       {
          uint16_t *data16 = (uint16_t *)data;
@@ -719,10 +799,9 @@ void Document::LoadEntryBinArea(DataEntry *entry)
       }
       case 8:
       {
-         gdcmWarningMacro("Can't swap 64 bits data");
-/*         uint64_t *data64 = (uint64_t *)data;
+         double *data64 = (double *)data;
          for(i=0;i<l/vrLgth;i++)
-            data64[i] = SwapLongLong(data64[i]);*/
+            data64[i] = SwapDouble(data64[i]);
          break;
       }
    }
@@ -862,7 +941,6 @@ uint32_t Document::ReadInt32()
 
 /**
  * \brief skips bytes inside the source file 
- * \warning NOT end user intended method !
  * @return 
  */
 void Document::SkipBytes(uint32_t nBytes)
@@ -872,7 +950,7 @@ void Document::SkipBytes(uint32_t nBytes)
 }
 
 /**
- * \brief   Re-computes the length of a ACR-NEMA/Dicom group from a DcmHeader
+ * \brief   Re-computes the length of the Dicom group 0002.
  */
 int Document::ComputeGroup0002Length( ) 
 {
@@ -896,10 +974,6 @@ int Document::ComputeGroup0002Length( )
          {
             vr = entry->GetVR();
 
-            // FIXME : group 0x0002 is *always* Explicit VR!
-            //if ( filetype == ExplicitVR )
-            //{
             //if ( (vr == "OB")||(vr == "OW")||(vr == "UT")||(vr == "SQ"))
             // (no SQ, OW, UT in group 0x0002;)
                if ( vr == "OB" ) 
@@ -907,7 +981,7 @@ int Document::ComputeGroup0002Length( )
                   // explicit VR AND (OB, OW, SQ, UT) : 4 more bytes
                   groupLength +=  4;
                }
-            //}
             groupLength += 2 + 2 + 4 + entry->GetLength();   
          }
       }
@@ -923,7 +997,6 @@ int Document::ComputeGroup0002Length( )
 // Private
 /**
  * \brief Loads all the needed Dictionaries
- * \warning NOT end user intended method !   
  */
 void Document::Initialize() 
 {
@@ -950,7 +1023,7 @@ void Document::ParseDES(DocEntrySet *set, long offset,
               // (Entry will then be deleted)
    bool delim_mode_intern = delim_mode;
    bool first = true;
-   gdcmWarningMacro( "Enter in ParseDES, delim-mode " <<  delim_mode
+   gdcmDebugMacro( "Enter in ParseDES, delim-mode " <<  delim_mode
                      << " at offset " << std::hex << offset ); 
    while (true)
    {
@@ -961,19 +1034,10 @@ void Document::ParseDES(DocEntrySet *set, long offset,
 
       newDocEntry = ReadNextDocEntry( );
 
-      // FIXME :
-      // Private tag, in IMplicit VR are defaulted as a DataEntry,
-      // Very often they are only composed of Printable characters, 
-      // and could be defaulted as a DataEntry.
-      // It's too late to do the Job
-      // (we should check the value, but we know it after LoadDocEntry ...)
-
-      // Uncoment this printf line to be able to 'follow' the DocEntries
+      // Uncoment this cerr line to be able to 'follow' the DocEntries
       // when something *very* strange happens
-
-      //printf( "%04x|%04x %s\n",newDocEntry->GetGroup(), 
-      //                     newDocEntry->GetElement(),
-      //                     newDocEntry->GetVR().c_str() );
+      if( Debug::GetDebugFlag() ) 
+         std::cerr<<newDocEntry->GetKey()<<" "<<newDocEntry->GetVR()<<std::endl;
 
       if ( !newDocEntry )
       {
@@ -985,8 +1049,9 @@ void Document::ParseDES(DocEntrySet *set, long offset,
        // but we didn't get it (private Sequence + Implicit VR)
        // we have to backtrack.
       if ( !first && newDocEntry->IsItemStarter() )
-      {
-         newDocEntry = Backtrack(newDocEntry); 
+      { 
+        // Debug message within the method !      
+        newDocEntry = Backtrack(newDocEntry); 
       }
       else
       { 
@@ -1001,24 +1066,10 @@ void Document::ParseDES(DocEntrySet *set, long offset,
          //////////////////////////// DataEntry
  
          vr = newDocEntry->GetVR();
-         // Useless checking, now !
-         /*
-         if ( Filetype == ExplicitVR && 
-               !Global::GetVR()->IsVROfBinaryRepresentable(vr) )
-         { 
-               ////// No DataEntry: should mean UNKOWN VR
-               gdcmWarningMacro( std::hex << newDocEntry->GetGroup() 
-                                 << "|" << newDocEntry->GetElement()
-                                 << " : unknown VR." 
-                                 " Probably 'Implicit VR' entry within "
-                                 "an explicit VR 'document'.");
-         }
-         */
 
          if ( !set->AddEntry( newDataEntry ) )
          {
-            gdcmWarningMacro( "in ParseDES : cannot add a DataEntry "
+            gdcmDebugMacro( "in ParseDES : cannot add a DataEntry "
                                  << newDataEntry->GetKey()  
                                  << " (at offset : " 
                                  << newDataEntry->GetOffset() << " )" );
@@ -1127,7 +1178,7 @@ void Document::ParseDES(DocEntrySet *set, long offset,
          if ( l != 0 )
          {  // Don't try to parse zero-length sequences
 
-            gdcmWarningMacro( "Entry in ParseSQ, delim " << delim_mode_intern
+            gdcmDebugMacro( "Entry in ParseSQ, delim " << delim_mode_intern
                                << " at offset " << std::hex
                                << newDocEntry->GetOffset() );
 
@@ -1135,7 +1186,7 @@ void Document::ParseDES(DocEntrySet *set, long offset,
                      newDocEntry->GetOffset(),
                      l, delim_mode_intern);
 
-            gdcmWarningMacro( "Exit from ParseSQ, delim " << delim_mode_intern);
+            gdcmDebugMacro( "Exit from ParseSQ, delim " << delim_mode_intern);
  
          }
          if ( !set->AddEntry( newSeqEntry ) )
@@ -1186,7 +1237,6 @@ void Document::ParseSQ( SeqEntry *seqEntry,
 
       if ( !newDocEntry )
       {
-         // FIXME Should warn user
          gdcmWarningMacro("in ParseSQ : should never get here!");
          break;
       }
@@ -1217,7 +1267,6 @@ void Document::ParseSQ( SeqEntry *seqEntry,
          dlm_mod = false;
       }
 
-      // Let's try :------------
       // remove fff0,e000, created out of the SQItem
       Fp->seekg(offsetStartCurrentSQItem, std::ios::beg);
       // fill up the current SQItem, starting at the beginning of fff0,e000
@@ -1225,7 +1274,6 @@ void Document::ParseSQ( SeqEntry *seqEntry,
       ParseDES(itemSQ, offsetStartCurrentSQItem, l+8, dlm_mod);
 
       offsetStartCurrentSQItem = Fp->tellg();
-      // end try -----------------
  
       seqEntry->AddSQItem( itemSQ, SQItemNumber ); 
       itemSQ->Delete();
@@ -1256,7 +1304,7 @@ DocEntry *Document::Backtrack(DocEntry *docEntry)
    uint32_t lgt   = PreviousDocEntry->GetLength();
    long offset    = PreviousDocEntry->GetOffset();
 
-   gdcmWarningMacro( "Backtrack :" << std::hex << group 
+   gdcmDebugMacro( "Backtrack :" << std::hex << group 
                                    << "|" << elem
                                    << " at offset " << offset );
    RemoveEntry( PreviousDocEntry );
@@ -1316,8 +1364,7 @@ void Document::LoadDocEntry(DocEntry *entry, bool forceLoad)
    }
 
    // The elements whose length is bigger than the specified upper bound
-   // are not loaded. Instead we leave a short notice on the offset of
-   // the element content and it's length.
+   // are not loaded.
 
    std::ostringstream s;
 
@@ -1416,7 +1463,8 @@ void Document::FindDocEntryLength( DocEntry *entry )
       // Length is on 4 bytes.
 
      // Well ... group 0002 is always coded in 'Explicit VR Litle Endian'
-     // even if Transfer Syntax is 'Implicit VR ...' 
+     // even if Transfer Syntax is 'Implicit VR ...'
+     // --> Except for 'Implicit VR Big Endian Transfer Syntax GE Private' 
       
       FixDocEntryFoundLength( entry, ReadInt32() );
       return;
@@ -1425,7 +1473,6 @@ void Document::FindDocEntryLength( DocEntry *entry )
 
 /**
  * \brief  Find the Length till the next sequence delimiter
- * \warning NOT end user intended method !
  * @return 
  */
 uint32_t Document::FindDocEntryLengthOBOrOW()
@@ -1493,20 +1540,24 @@ VRKey Document::FindDocEntryVR()
 
    long positionOnEntry = Fp->tellg();
    // Warning: we believe this is explicit VR (Value Representation) because
-   // we used a heuristic that found "UL" in the first tag. Alas this
-   // doesn't guarantee that all the tags will be in explicit VR. In some
-   // cases (see e-film filtered files) one finds implicit VR tags mixed
-   // within an explicit VR file. Hence we make sure the present tag
-   // is in explicit VR and try to fix things if it happens not to be
-   // the case.
+   // we used a heuristic that found "UL" in the first tag and/or
+   // 'Transfer Syntax' told us it is.
+   // Alas this doesn't guarantee that all the tags will be in explicit VR. 
+   // In some cases one finds implicit VR tags mixed within an explicit VR file.
+   // Hence we make sure the present tag is in explicit VR and try to fix things
+   // if it happens not to be the case.
 
    VRKey vr;
    Fp->read(&(vr[0]),(size_t)2);
 
-   //gdcmDebugMacro( "--> VR: " << vr )
    if ( !CheckDocEntryVR(vr) )
    {
-      gdcmWarningMacro( "Unknown VR '" << vr << "'" )
+      // Don't warn user with useless messages
+      // Often, delimiters (0xfffe), are not explicit VR ...
+      if ( CurrentGroup != 0xfffe )
+         gdcmWarningMacro( "Unknown VR " << std::hex << "0x(" 
+                        << (unsigned int)vr[0] << "|" << (unsigned int)vr[1] 
+                        << ") at offset :" << positionOnEntry );
       Fp->seekg(positionOnEntry, std::ios::beg);
       return GDCM_VRUNKNOWN;
    }
@@ -1528,7 +1579,6 @@ bool Document::CheckDocEntryVR(const VRKey &vr)
 
 /**
  * \brief   Skip a given Header Entry 
- * \warning NOT end user intended method !
  * @param   entry entry to skip
  */
 void Document::SkipDocEntry(DocEntry *entry) 
@@ -1538,7 +1588,6 @@ void Document::SkipDocEntry(DocEntry *entry)
 
 /**
  * \brief   Skips to the beginning of the next Header Entry 
- * \warning NOT end user intended method !
  * @param   currentDocEntry entry to skip
  */
 void Document::SkipToNextDocEntry(DocEntry *currentDocEntry) 
@@ -1640,7 +1689,7 @@ bool Document::IsDocEntryAnInteger(DocEntry *entry)
 {
    uint16_t elem         = entry->GetElement();
    uint16_t group        = entry->GetGroup();
-   const VRKey &vr = entry->GetVR();
+   const VRKey &vr       = entry->GetVR();
    uint32_t length       = entry->GetLength();
 
    // When we have some semantics on the element we just read, and if we
@@ -1739,19 +1788,19 @@ bool Document::CheckSwap()
       else 
       {
          Filetype = ImplicitVR;
-         gdcmErrorMacro( "Group 0002 :Not an explicit Value Representation;"
+         gdcmWarningMacro( "Group 0002 :Not an explicit Value Representation;"
                         << "Looks like a bugged Header!");
       }
       
       if ( net2host )
       {
          SwapCode = 4321;
-         gdcmDebugMacro( "HostByteOrder != NetworkByteOrder");
+         gdcmDebugMacro( "HostByteOrder != NetworkByteOrder, SwapCode = 4321");
       }
       else 
       {
          SwapCode = 1234;
-         gdcmDebugMacro( "HostByteOrder = NetworkByteOrder");
+         gdcmDebugMacro( "HostByteOrder = NetworkByteOrder, SwapCode = 1234");
       }
       
       // Position the file position indicator at first tag 
@@ -1935,13 +1984,10 @@ void Document::SetMaxSizeLoadEntry(long newSize)
  */
 DocEntry *Document::ReadNextDocEntry()
 {
-   uint16_t group;
-   uint16_t elem;
-
    try
    {
-      group = ReadInt16();
-      elem  = ReadInt16();
+      CurrentGroup = ReadInt16();
+      CurrentElem  = ReadInt16();
    }
    catch ( FormatError )
    {
@@ -1951,11 +1997,11 @@ DocEntry *Document::ReadNextDocEntry()
    }
 
    // Sometimes file contains groups of tags with reversed endianess.
-   HandleBrokenEndian(group, elem);
+   HandleBrokenEndian(CurrentGroup, CurrentElem);
 
    // In 'true DICOM' files Group 0002 is always little endian
    if ( HasDCMPreamble )
-      HandleOutOfGroup0002(group, elem);
+      HandleOutOfGroup0002(CurrentGroup, CurrentElem);
  
    VRKey vr = FindDocEntryVR();
    
@@ -1963,11 +2009,12 @@ DocEntry *Document::ReadNextDocEntry()
 
    if ( vr == GDCM_VRUNKNOWN )
    {
-      if ( elem == 0x0000 ) // Group Length
+      if ( CurrentElem == 0x0000 ) // Group Length
       {
          realVR = "UL";     // must be UL
       }
-      else if (group%2 == 1 &&  (elem >= 0x0010 && elem <=0x00ff ))
+      else if (CurrentGroup%2 == 1 &&  
+                               (CurrentElem >= 0x0010 && CurrentElem <=0x00ff ))
       {  
       // DICOM PS 3-5 7.8.1 a) states that those 
       // (gggg-0010->00FF where gggg is odd) attributes have to be LO
@@ -1975,7 +2022,7 @@ DocEntry *Document::ReadNextDocEntry()
       }
       else
       {
-         DictEntry *dictEntry = GetDictEntry(group,elem);
+         DictEntry *dictEntry = GetDictEntry(CurrentGroup,CurrentElem);
          if ( dictEntry )
          {
             realVR = dictEntry->GetVR();
@@ -1987,10 +2034,10 @@ DocEntry *Document::ReadNextDocEntry()
 
    DocEntry *newEntry;
    if ( Global::GetVR()->IsVROfSequence(realVR) )
-      newEntry = NewSeqEntry(group, elem);
+      newEntry = NewSeqEntry(CurrentGroup, CurrentElem);
    else 
    {
-      newEntry = NewDataEntry(group, elem, realVR);
+      newEntry = NewDataEntry(CurrentGroup, CurrentElem, realVR);
       static_cast<DataEntry *>(newEntry)->SetState(DataEntry::STATE_NOTLOADED);
    }
 
@@ -2044,6 +2091,7 @@ void Document::HandleBrokenEndian(uint16_t &group, uint16_t &elem)
    if ((group == 0xfeff) && (elem == 0x00e0))
    {
      // start endian swap mark for group found
+     gdcmDebugMacro( "Start endian swap mark found." );
      reversedEndian++;
      SwitchByteSwapCode();
      // fix the tag
@@ -2053,6 +2101,7 @@ void Document::HandleBrokenEndian(uint16_t &group, uint16_t &elem)
    else if (group == 0xfffe && elem == 0xe00d && reversedEndian) 
    {
      // end of reversed endian group
+     gdcmDebugMacro( "End of reversed endian." );
      reversedEndian--;
      SwitchByteSwapCode();
    }
@@ -2070,7 +2119,7 @@ void Document::HandleBrokenEndian(uint16_t &group, uint16_t &elem)
    }
    else if (group == 0xfffe && elem == 0xe0dd) 
    {
-      gdcmWarningMacro( "Straight Sequence Terminator." );  
+      gdcmDebugMacro( "Straight Sequence Terminator." );  
    }
 }
 
@@ -2087,12 +2136,18 @@ void Document::HandleOutOfGroup0002(uint16_t &group, uint16_t &elem)
    {
       Group0002Parsed = true;
       // we just came out of group 0002
-      // if Transfer syntax is Big Endian we have to change CheckSwap
+      // if Transfer Syntax is Big Endian we have to change CheckSwap
 
       std::string ts = GetTransferSyntax();
+      if ( ts == GDCM_UNKNOWN )
+      {
+         gdcmDebugMacro("True DICOM File, with NO Transfer Syntax (?!) " );
+         return;      
+      }
       if ( !Global::GetTS()->IsTransferSyntax(ts) )
       {
-         gdcmWarningMacro("True DICOM File, with NO Tansfer Syntax: " << ts );
+         gdcmWarningMacro("True DICOM File, with illegal Transfer Syntax: [" 
+                          << ts << "]");
          return;
       }
 
@@ -2101,9 +2156,9 @@ void Document::HandleOutOfGroup0002(uint16_t &group, uint16_t &elem)
 
       if ( Global::GetTS()->GetSpecialTransferSyntax(ts) == 
                                                     TS::ImplicitVRLittleEndian )
-         {
-            Filetype = ImplicitVR;
-         }
+      {
+         Filetype = ImplicitVR;
+      }
        
       // FIXME Strangely, this works with 
       //'Implicit VR BigEndian Transfer Syntax (GE Private)
@@ -2115,7 +2170,7 @@ void Document::HandleOutOfGroup0002(uint16_t &group, uint16_t &elem)
       if ( Global::GetTS()->GetSpecialTransferSyntax(ts) == 
                                                        TS::ExplicitVRBigEndian )
       {
-         gdcmWarningMacro("Transfer Syntax Name = [" 
+         gdcmDebugMacro("Transfer Syntax Name = [" 
                         << GetTransferSyntaxName() << "]" );
          SwitchByteSwapCode();
          group = SwapShort(group);