]> Creatis software - gdcm.git/blobdiff - src/gdcmDocument.cxx
BUG: Fix declaration of vars within a switch/case
[gdcm.git] / src / gdcmDocument.cxx
index 5e33c4c1d1575b85ef3c0e4c35df649fa48d658e..481752945178cfb211ee4640383a2eca0aab537b 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmDocument.cxx,v $
   Language:  C++
-  Date:      $Date: 2005/10/20 13:55:05 $
-  Version:   $Revision: 1.300 $
+  Date:      $Date: 2005/10/26 17:06:33 $
+  Version:   $Revision: 1.312 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -386,7 +386,8 @@ FileType Document::GetFileType()
  * \brief   Accessor to the Transfer Syntax (when present) of the
  *          current document (it internally handles reading the
  *          value from disk when only parsing occured).
- * @return  The encountered Transfer Syntax of the current document.
+ * @return  The encountered Transfer Syntax of the current document, if DICOM.
+ *          GDCM_UNKNOWN for ACR-NEMA files (or broken headers ...)
  */
 std::string Document::GetTransferSyntax()
 {
@@ -500,6 +501,43 @@ uint32_t Document::SwapLong(uint32_t a)
    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( "Unset swap code:" << SwapCode );
+         a = 0.;
+   }
+   return a;
+} 
+
+
 //
 // -----------------File I/O ---------------
 /**
@@ -605,7 +643,7 @@ void Document::WriteContent(std::ofstream *fp, FileType filetype)
    // Skip if user wants to write an ACR-NEMA file
 
    if ( filetype == ImplicitVR || filetype == ExplicitVR ||
-     filetype == JPEG )
+        filetype == JPEG )
    {
       // writing Dicom File Preamble
       char filePreamble[128];
@@ -660,7 +698,7 @@ void Document::LoadEntryBinArea(uint16_t group, uint16_t elem)
 /**
  * \brief Loads (from disk) the element content 
  *        when a string is not suitable
- * @param elem  Entry whose binArea is going to be loaded
+ * @param entry  Entry whose binArea is going to be loaded
  */
 void Document::LoadEntryBinArea(DataEntry *entry) 
 {
@@ -684,7 +722,7 @@ void Document::LoadEntryBinArea(DataEntry *entry)
       return;
    }
 
-   // Read the datas
+   // Read the data
    Fp->read((char*)data, l);
    if ( Fp->fail() || Fp->eof() )
    {
@@ -718,10 +756,9 @@ void Document::LoadEntryBinArea(DataEntry *entry)
       }
       case 8:
       {
-         gdcmWarningMacro("Can't swap 64 bits datas");
-/*         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;
       }
    }
@@ -903,7 +940,7 @@ int Document::ComputeGroup0002Length( )
             // (no SQ, OW, UT in group 0x0002;)
                if ( vr == "OB" ) 
                {
-                  // explicit VR AND OB, OW, SQ, UT : 4 more bytes
+                  // explicit VR AND (OB, OW, SQ, UT) : 4 more bytes
                   groupLength +=  4;
                }
             //}
@@ -967,12 +1004,11 @@ void Document::ParseDES(DocEntrySet *set, long offset,
       // 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 )
       {
@@ -998,16 +1034,22 @@ void Document::ParseDES(DocEntrySet *set, long offset,
       if ( newDataEntry )  
       {
          //////////////////////////// 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()
-                                 << " : No DataEntry." 
-                                 "Probably unknown VR.");
+                                 << " : unknown VR." 
+                                 " Probably 'Implicit VR' entry within "
+                                 "an explicit VR 'document'.");
          }
+         */
 
          if ( !set->AddEntry( newDataEntry ) )
          {
@@ -1019,6 +1061,7 @@ void Document::ParseDES(DocEntrySet *set, long offset,
          }
          else
          {
+            newDataEntry->Delete();
             // Load only if we can add (not a duplicate key)
             LoadDocEntry( newDataEntry );
          }
@@ -1051,7 +1094,7 @@ void Document::ParseDES(DocEntrySet *set, long offset,
                (!delim_mode && ((long)(Fp->tellg())-offset) >= l_max) )
          {
             if ( !used )
-               delete newDocEntry;
+               newDocEntry->Delete();
             break;
          }
 
@@ -1081,7 +1124,7 @@ void Document::ParseDES(DocEntrySet *set, long offset,
             if ( newDocEntry->GetGroup()%2 != 0 )
             {
                 Fp->seekg( l, std::ios::cur);
-                delete newDocEntry;  // Delete, not in the set 
+                newDocEntry->Delete();  // Delete, not in the set 
                 continue;  
             } 
          } 
@@ -1089,7 +1132,7 @@ void Document::ParseDES(DocEntrySet *set, long offset,
          {
            // User asked to skip *any* SeQuence
             Fp->seekg( l, std::ios::cur);
-            delete newDocEntry; // Delete, not in the set
+            newDocEntry->Delete(); // Delete, not in the set
             continue;
          }
          // delay the dynamic cast as late as possible
@@ -1138,18 +1181,22 @@ void Document::ParseDES(DocEntrySet *set, long offset,
                                 << newSeqEntry->GetOffset() << " )" ); 
             used = false;
          }
+         else
+         {
+            newDocEntry->Delete();
+         }
  
          if ( !delim_mode && ((long)(Fp->tellg())-offset) >= l_max)
          {
             if ( !used )
-               delete newDocEntry;  
-               break;
+               newDocEntry->Delete();
+            break;
          }
       }  // end SeqEntry : VR = "SQ"
 
       if ( !used )
       {
-         delete newDocEntry;
+         newDocEntry->Delete();
       }
       first = false;
    }                               // end While
@@ -1183,16 +1230,17 @@ void Document::ParseSQ( SeqEntry *seqEntry,
          if ( newDocEntry->IsSequenceDelimitor() )
          {
             seqEntry->SetDelimitationItem( newDocEntry ); 
+            newDocEntry->Delete();
             break;
          }
       }
       if ( !delim_mode && ((long)(Fp->tellg())-offset) >= l_max)
       {
-         delete newDocEntry;
+         newDocEntry->Delete();
          break;
       }
       // create the current SQItem
-      SQItem *itemSQ = new SQItem( seqEntry->GetDepthLevel() );
+      SQItem *itemSQ = SQItem::New( seqEntry->GetDepthLevel() );
       unsigned int l = newDocEntry->GetReadLength();
       
       if ( l == 0xffffffff )
@@ -1206,7 +1254,6 @@ void Document::ParseSQ( SeqEntry *seqEntry,
 
       // Let's try :------------
       // remove fff0,e000, created out of the SQItem
-      delete newDocEntry;
       Fp->seekg(offsetStartCurrentSQItem, std::ios::beg);
       // fill up the current SQItem, starting at the beginning of fff0,e000
 
@@ -1216,6 +1263,8 @@ void Document::ParseSQ( SeqEntry *seqEntry,
       // end try -----------------
  
       seqEntry->AddSQItem( itemSQ, SQItemNumber ); 
+      itemSQ->Delete();
+      newDocEntry->Delete();
       SQItemNumber++;
       if ( !delim_mode && ((long)(Fp->tellg())-offset ) >= l_max )
       {
@@ -1234,7 +1283,7 @@ DocEntry *Document::Backtrack(DocEntry *docEntry)
 {
    // delete the Item Starter, built erroneously out of any Sequence
    // it's not yet in the HTable/chained list
-   delete docEntry;
+   docEntry->Delete();
 
    // Get all info we can from PreviousDocEntry
    uint16_t group = PreviousDocEntry->GetGroup();
@@ -1489,10 +1538,11 @@ VRKey Document::FindDocEntryVR()
    VRKey vr;
    Fp->read(&(vr[0]),(size_t)2);
 
-   gdcmDebugMacro( "--> VR: " << vr )
+   //gdcmDebugMacro( "--> VR: " << vr )
    if ( !CheckDocEntryVR(vr) )
    {
-      gdcmWarningMacro( "Unknown VR '" << vr << "'" )
+      gdcmWarningMacro( "Unknown VR '" << vr << "' at offset :"
+                        << positionOnEntry );
       Fp->seekg(positionOnEntry, std::ios::beg);
       return GDCM_VRUNKNOWN;
    }
@@ -1965,10 +2015,11 @@ DocEntry *Document::ReadNextDocEntry()
          if ( dictEntry )
          {
             realVR = dictEntry->GetVR();
+            dictEntry->Unregister();
          }
       }
    }
-   gdcmDebugMacro( "Found VR: " << vr << " / Real VR: " << realVR );
+  // gdcmDebugMacro( "Found VR: " << vr << " / Real VR: " << realVR );
 
    DocEntry *newEntry;
    if ( Global::GetVR()->IsVROfSequence(realVR) )
@@ -2005,7 +2056,7 @@ DocEntry *Document::ReadNextDocEntry()
    catch ( FormatError )
    {
       // Call it quits
-      delete newEntry;
+      newEntry->Delete();
       return 0;
    }