]> Creatis software - gdcm.git/commitdiff
Jean-Pierre Roux
authorjpr <jpr>
Thu, 24 Jun 2004 18:03:14 +0000 (18:03 +0000)
committerjpr <jpr>
Thu, 24 Jun 2004 18:03:14 +0000 (18:03 +0000)
FIX : Write - All the Sequences and Sequence Item are now written
            as 'no length' stuff, and a Sequence Delimitor aor an Item Delimitor
is added a the end, when necessary.
            - A lot of brain-damaged images, that were read correctly are
      now written correctly
- length compatible BinEntry are now loaded correctly
(even for odd groups)
            - Note : only Explicit Value Representation was checked.
(question : is implicit VR really necessary for gdcm ?)

src/gdcmBinEntry.cxx
src/gdcmDocEntry.cxx
src/gdcmDocument.cxx
src/gdcmDocument.h
src/gdcmSQItem.cxx
src/gdcmSeqEntry.cxx
src/gdcmValEntry.cxx
src/gdcmValEntry.h

index e57f5dfbc7e9c5f0c206fdbfb73133a5cb64ce33..ae4c5be868395906260f7a5a65a114f2a1d498bc 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmBinEntry.cxx,v $
   Language:  C++
-  Date:      $Date: 2004/06/23 15:01:57 $
-  Version:   $Revision: 1.17 $
+  Date:      $Date: 2004/06/24 18:03:14 $
+  Version:   $Revision: 1.18 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -66,6 +66,7 @@ void gdcmBinEntry::Print(std::ostream &os)
 {
    gdcmDocEntry::Print(os);
    std::ostringstream s;
+   void *voidArea = GetVoidArea();     
    if (voidArea != NULL)
    {
       s << " [gdcm::Binary data loaded with length is "
@@ -73,7 +74,13 @@ void gdcmBinEntry::Print(std::ostream &os)
    }
    else
    {
-      s << " [gdcm::Binary data NOT loaded]";
+      if ( GetLength() == 0 )
+         s << " []";
+      else 
+      {
+         s << " [gdcm::Binary data NOT loaded]";
+      }
+         
    }
    os << s.str();
 }
index 522b16679d847e1eb9db5d11e76b47fb155b488a..69d07b069fb97817be3d4b1d21b653805abc9f9b 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmDocEntry.cxx,v $
   Language:  C++
-  Date:      $Date: 2004/06/23 13:02:36 $
-  Version:   $Revision: 1.9 $
+  Date:      $Date: 2004/06/24 18:03:14 $
+  Version:   $Revision: 1.10 $
                                                                                 
   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,7 @@ void gdcmDocEntry::Print(std::ostream & os) {
  */
 void gdcmDocEntry::Write(FILE *fp, FileType filetype) {
 
+   guint32 FFFF = 0xffffffff;
    guint16 group  = GetGroup();
    VRKey   vr     = GetVR();
    guint16 el     = GetElement();
@@ -151,13 +152,18 @@ void gdcmDocEntry::Write(FILE *fp, FileType filetype) {
          fwrite ( &z,  (size_t)2 ,(size_t)1 ,fp);
       } else {
          fwrite (vr.c_str(),(size_t)2 ,(size_t)1 ,fp); 
-
-// TODO : better we set SQ length to ffffffff
-//      and write a Sequence Delimitor Item at the end of the Sequence!                    
+                  
          if ( (vr == "OB") || (vr == "OW") || (vr == "SQ") )
          {
             fwrite ( &z,  (size_t)2 ,(size_t)1 ,fp);
-            fwrite ( &lgr,(size_t)4 ,(size_t)1 ,fp);
+            if (vr == "SQ") {
+            // we set SQ length to ffffffff
+            // and  we shall write a Sequence Delimitor Item 
+            // at the end of the Sequence! 
+               fwrite ( &FFFF,(size_t)4 ,(size_t)1 ,fp);
+            } else {
+               fwrite ( &lgr,(size_t)4 ,(size_t)1 ,fp);
+            }
          } else {
             fwrite ( &shortLgr,(size_t)2 ,(size_t)1 ,fp);
          }
@@ -165,7 +171,11 @@ void gdcmDocEntry::Write(FILE *fp, FileType filetype) {
    } 
    else // IMPLICIT VR 
    { 
-      fwrite ( &lgr,(size_t)4 ,(size_t)1 ,fp);
+      if (vr == "SQ") {
+          fwrite ( &FFFF,(size_t)4 ,(size_t)1 ,fp);
+       } else {
+          fwrite ( &lgr,(size_t)4 ,(size_t)1 ,fp);
+       }
    }
 }
 
@@ -205,7 +215,8 @@ void gdcmDocEntry::Copy (gdcmDocEntry* e) {
 
 /**
  * \ingroup gdcmDocEntry
- * \brief   tells us if entry is the first one of a Sequence Item (fffe,e00d) 
+ * \brief   tells us if entry is the last one of a 'no length' SequenceItem 
+ *          (fffe,e00d) 
  */
 bool gdcmDocEntry::isItemDelimitor() {
    if ( (GetGroup() == 0xfffe) && (GetElement() == 0xe00d) )
@@ -215,7 +226,8 @@ bool gdcmDocEntry::isItemDelimitor() {
 }
 /**
  * \ingroup gdcmDocEntry
- * \brief   tells us if entry is the last one of a 'no length' Sequence fffe,e0dd) 
+ * \brief   tells us if entry is the last one of a 'no length' Sequence 
+ *          (fffe,e0dd) 
  */
 bool gdcmDocEntry::isSequenceDelimitor() {
    if (GetGroup() == 0xfffe && GetElement() == 0xe0dd)
index bf4d3d49f0025c3bda9496ec3f857e13a7a1407b..5a71e670ea2c37d3ee12af5eb75f70513a85d4fa 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmDocument.cxx,v $
   Language:  C++
-  Date:      $Date: 2004/06/23 16:34:36 $
-  Version:   $Revision: 1.31 $
+  Date:      $Date: 2004/06/24 18:03:14 $
+  Version:   $Revision: 1.32 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -74,9 +74,9 @@
 const unsigned int gdcmDocument::HEADER_LENGTH_TO_READ = 256;
 
 // Refer to gdcmDocument::SetMaxSizeLoadEntry()
-const unsigned int gdcmDocument::MAX_SIZE_LOAD_ELEMENT_VALUE = 4096;
+const unsigned int gdcmDocument::MAX_SIZE_LOAD_ELEMENT_VALUE = 0x7fffffff;// 4096;
 
-const unsigned int gdcmDocument::MAX_SIZE_PRINT_ELEMENT_VALUE = 64;
+const unsigned int gdcmDocument::MAX_SIZE_PRINT_ELEMENT_VALUE = 0x7fffffff;//64;
 
 //-----------------------------------------------------------------------------
 // Constructor / Destructor
@@ -126,8 +126,8 @@ gdcmDocument::gdcmDocument(std::string const & inFilename,
    
    long l=ParseDES( this, beg, lgt, false); // le Load sera fait a la volee
    (void)l; //is l used anywhere ?
-       
-       rewind(fp); 
+
+   rewind(fp); 
    
    // Load 'non string' values
       
@@ -144,7 +144,7 @@ gdcmDocument::gdcmDocument(std::string const & inFilename,
    } 
    //FIXME later : how to use it?
    LoadEntryVoidArea(0x0028,0x3006);  //LUT Data (CTX dependent) 
-               
+
    CloseFile(); 
   
    // --------------------------------------------------------------
@@ -571,10 +571,9 @@ bool gdcmDocument::WriteF(FileType filetype) {
  * if ( filetype == ACR)
  *    UpdateGroupLength(true,ACR);
  */
-       
-       gdcmElementSet::Write(fp,filetype);
+   gdcmElementSet::Write(fp,filetype);
 
-   /// WriteEntries(fp,type); // old stuff
    return true;
 }
 
@@ -968,7 +967,31 @@ void *gdcmDocument::LoadEntryVoidArea(guint16 Group, guint16 Elem)
       delete[] a;
       return NULL;
    }
-
+   return a;  
+}
+/**
+ * \brief         Loads (from disk) the element content 
+ *                when a string is not suitable
+ * @param Element  Entry whose voidArea is going to be loaded
+ */
+void *gdcmDocument::LoadEntryVoidArea(gdcmBinEntry *Element) 
+{
+   size_t o =(size_t)Element->GetOffset();
+   fseek(fp, o, SEEK_SET);
+   size_t l = Element->GetLength();
+   char* a = new char[l];
+   if(!a) {
+      dbg.Verbose(0, "gdcmDocument::LoadEntryVoidArea cannot allocate a");
+      return NULL;
+   }
+   Element->SetVoidArea((void *)a);
+   /// \todo check the result 
+   size_t l2 = fread(a, 1, l ,fp);
+   if(l != l2) 
+   {
+      delete[] a;
+      return NULL;
+   }
    return a;  
 }
 
@@ -1066,7 +1089,7 @@ void gdcmDocument::UpdateShaEntries(void) {
  */
 gdcmDocEntry* gdcmDocument::GetDocEntryByNumber(guint16 group, guint16 element) 
 {
-   TagKey key = gdcmDictEntry::TranslateToKey(group, element);   
+   TagKey key = gdcmDictEntry::TranslateToKey(group, element);
    if ( ! tagHT.count(key))
       return NULL;
    return tagHT.find(key)->second;
@@ -1364,11 +1387,11 @@ void gdcmDocument::LoadDocEntry(gdcmDocEntry *Entry)
    // The elements whose length is bigger than the specified upper bound
    // are not loaded. Instead we leave a short notice of the offset of
    // the element content and it's length.
-       
+
+   std::ostringstream s;
    if (length > MaxSizeLoadEntry) {
       if (gdcmBinEntry* BinEntryPtr = dynamic_cast< gdcmBinEntry* >(Entry) )
-      {
-         std::ostringstream s;
+      {         
          s << "gdcm::NotLoaded (BinEntry)";
          s << " Address:" << (long)Entry->GetOffset();
          s << " Length:"  << Entry->GetLength();
@@ -1377,17 +1400,16 @@ void gdcmDocument::LoadDocEntry(gdcmDocEntry *Entry)
       }
       // to be sure we are at the end of the value ...
       fseek(fp,(long)Entry->GetOffset()+(long)Entry->GetLength(),SEEK_SET);      
-      return;          
-       // Be carefull : a BinEntry IS_A ValEntry ...   
+      return;
+       // Be carefull : a BinEntry IS_A ValEntry ... 
       if (gdcmValEntry* ValEntryPtr = dynamic_cast< gdcmValEntry* >(Entry) )
       {
-         std::ostringstream s;
          s << "gdcm::NotLoaded. (ValEntry)";
          s << " Address:" << (long)Entry->GetOffset();
          s << " Length:"  << Entry->GetLength();
          s << " x(" << std::hex << Entry->GetLength() << ")";
          ValEntryPtr->SetValue(s.str());
-      }                
+      }
       // to be sure we are at the end of the value ...
       fseek(fp,(long)Entry->GetOffset()+(long)Entry->GetLength(),SEEK_SET);      
       return;
@@ -1395,9 +1417,12 @@ void gdcmDocument::LoadDocEntry(gdcmDocEntry *Entry)
 
    // When we find a BinEntry not very much can be done :
    if (gdcmBinEntry* BinEntryPtr = dynamic_cast< gdcmBinEntry* >(Entry) ) {
-      LoadEntryVoidArea (BinEntryPtr->GetGroup(),BinEntryPtr->GetElement());
-               return; 
-       }
+       
+      LoadEntryVoidArea(BinEntryPtr);
+      s << "gdcm::Loaded (BinEntry)";          
+      BinEntryPtr->SetValue(s.str());
+      return;
+   }
  
     
    // Any compacter code suggested (?)
@@ -1448,7 +1473,7 @@ void gdcmDocument::LoadDocEntry(gdcmDocEntry *Entry)
    // We need an additional byte for storing \0 that is not on disk
    std::string NewValue(length,0);
    item_read = fread(&(NewValue[0]), (size_t)length, (size_t)1, fp);
-       if (gdcmValEntry* ValEntry = dynamic_cast< gdcmValEntry* >(Entry) ) {  
+   if (gdcmValEntry* ValEntry = dynamic_cast< gdcmValEntry* >(Entry) ) {  
       if ( item_read != 1 ) {
          dbg.Verbose(1, "gdcmDocument::LoadElementValue","unread element value");
          ValEntry->SetValue("gdcm::UnRead");
@@ -1460,9 +1485,9 @@ void gdcmDocument::LoadDocEntry(gdcmDocEntry *Entry)
       else
          ValEntry->SetValue(NewValue);
    } else {
-       // fusible
-       std::cout << "Should have a ValEntry, here !" << std::endl;
-       }
+   // fusible
+      std::cout << "Should have a ValEntry, here !" << std::endl;
+   }
 
 }
 
index 5a85583e8e3ffdd8ab0f46b95e19728a24a127f8..4a5873f0495153b5091a008050edc837e6b14577 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmDocument.h,v $
   Language:  C++
-  Date:      $Date: 2004/06/22 14:57:11 $
-  Version:   $Revision: 1.14 $
+  Date:      $Date: 2004/06/24 18:03:14 $
+  Version:   $Revision: 1.15 $
  
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -152,6 +152,7 @@ public:
    bool ReplaceIfExistByNumber (char *Value, guint16 Group, guint16 Elem);
    
    virtual void  *LoadEntryVoidArea       (guint16 Group, guint16 Element);
+   virtual void  *LoadEntryVoidArea       (gdcmBinEntry*);
       
    // System access
    guint16 SwapShort(guint16);   // needed by gdcmFile
index f0fa250394cedf412acf42db1689260e92bb3271..417093d03ce42351cf21bda9114e74fc4fe569ce 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmSQItem.cxx,v $
   Language:  C++
-  Date:      $Date: 2004/06/23 13:02:36 $
-  Version:   $Revision: 1.16 $
+  Date:      $Date: 2004/06/24 18:03:14 $
+  Version:   $Revision: 1.17 $
   
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -92,6 +92,19 @@ void gdcmSQItem::Write(FILE *fp,FileType filetype)
         i != docEntries.end();
         ++i)
    {
+      // Item Delimitor Item IS the last one of a 'no length' SQItem
+      // (when it exists) we don't write it right now
+      // It will be written outside, because ALL the SQItems are written
+      // as 'no length'
+      if ( (*i)->isItemDelimitor() )
+         break;
+      if ( ((*i)->GetGroup() == 0xfffe) && ((*i)->GetElement() == 0x0000) ) 
+        // Fix in order to make some MR PHILIPS images e-film readable
+        // see gdcmData/gdcm-MR-PHILIPS-16-Multi-Seq.dcm:
+        // we just *always* ignore spurious fffe|0000 tag !   
+         return;                       
+      // It's up to the gdcmDocEntry Writter to write the SQItem begin element
+      // (fffe|e000) as a 'no length' one
       (*i)->Write(fp, filetype);
    } 
 }
index 6026a867e9b6187746f41fdf49450b7b2355ed2a..fd4d24993c019c7183da9ac5997c1bfa3df3eb66 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmSeqEntry.cxx,v $
   Language:  C++
-  Date:      $Date: 2004/06/23 15:01:57 $
-  Version:   $Revision: 1.19 $
+  Date:      $Date: 2004/06/24 18:03:14 $
+  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
@@ -45,7 +45,6 @@ gdcmSeqEntry::~gdcmSeqEntry() {
    for(ListSQItem::iterator cc = items.begin();cc != items.end();++cc)
    {
       delete *cc;
-     std::cout << "delete SQItem" <<std:: endl;
    }
    if (!seq_term)
       delete seq_term;
@@ -79,6 +78,7 @@ void gdcmSeqEntry::Print(std::ostream &os){
          os << std::endl;
       } 
       else 
+         // fusible
          os << "      -------------- should have a sequence terminator item";
    }                    
 }
@@ -88,13 +88,29 @@ void gdcmSeqEntry::Print(std::ostream &os){
  */
 void gdcmSeqEntry::Write(FILE *fp, FileType filetype)
 {
+   guint16 seq_term_gr = 0xfffe;
+   guint16 seq_term_el = 0xe0dd;
+   guint32 seq_term_lg = 0x00000000;
+
+   guint16 item_term_gr = 0xfffe;
+   guint16 item_term_el = 0xe00d;
+
    gdcmDocEntry::Write(fp, filetype);
    for(ListSQItem::iterator cc  = GetSQItems().begin();
                             cc != GetSQItems().end();
                           ++cc)
    {
-      (*cc)->Write(fp, filetype);   
-   }  
+      (*cc)->Write(fp, filetype);
+
+   fwrite ( &item_term_gr,(size_t)2 ,(size_t)1 ,fp);
+   fwrite ( &item_term_el,(size_t)2 ,(size_t)1 ,fp);   
+   fwrite ( &seq_term_lg,(size_t)4 ,(size_t)1 ,fp); 
+   }
+    //we force the writting of a Sequence Delimitaion item
+    // because we wrote the Sequence as a 'no Length' sequence
+   fwrite ( &seq_term_gr,(size_t)2 ,(size_t)1 ,fp);
+   fwrite ( &seq_term_el,(size_t)2 ,(size_t)1 ,fp);
+   fwrite ( &seq_term_lg,(size_t)4 ,(size_t)1 ,fp); 
 }
 
 //-----------------------------------------------------------------------------
index c0082d832bb279989dfb8cdf9822fb1630f99fad..3c58e70158dfddc08983a1af6b9a2439abf941e8 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmValEntry.cxx,v $
   Language:  C++
-  Date:      $Date: 2004/06/23 13:02:36 $
-  Version:   $Revision: 1.13 $
+  Date:      $Date: 2004/06/24 18:03:14 $
+  Version:   $Revision: 1.14 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -137,7 +137,7 @@ void gdcmValEntry::Write(FILE *fp, FileType filetype)
 {
    gdcmDocEntry::Write(fp, filetype);
    std::string vr=GetVR();
-   int lgr=GetLength();
+   int lgr=GetReadLength();
    if (vr == "US" || vr == "SS")
    {
       // some 'Short integer' fields may be mulivaluated
index 3adc99fa1a4172c98d000da6c207180c95caee2a..c2a21b84bb5057d012a3374486d65d5398b09c73 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmValEntry.h,v $
   Language:  C++
-  Date:      $Date: 2004/06/23 13:02:36 $
-  Version:   $Revision: 1.16 $
+  Date:      $Date: 2004/06/24 18:03:14 $
+  Version:   $Revision: 1.17 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -46,7 +46,10 @@ public:
     
    /// Sets the value (string) of the current Dicom Document Entry
    inline void SetValue(std::string val)  { value = val;  };
-   
+       
+   /// Sets the value (void *) of the current Dicom Document Entry
+   inline void SetVoidArea(void * val)  { voidArea = val;  };
+          
    virtual void Print(std::ostream &os = std::cout); 
    virtual void Write(FILE *fp, FileType filetype);
 protected:
@@ -59,7 +62,7 @@ private:
 // Members :
   
    /// \brief Document Entry value, internaly represented as a std::string
-   ///        The Value Representation (\ref gdcmVR) is indenpendently used
+   ///        The Value Representation (\ref gdcmVR) is independently used
    ///        in order to interpret (decode) this field.
    std::string  value;
 };