]> Creatis software - gdcm.git/blobdiff - src/gdcmDocEntry.cxx
BUG: There was two bombs at the same time. Guess what what I found them all
[gdcm.git] / src / gdcmDocEntry.cxx
index 668fbefcfc057662ceb3ae6c7bd5199daf377b36..5b1a9f3bc530d230a319e6d6645b58f300d57e3b 100644 (file)
@@ -1,6 +1,20 @@
-// gdcmDocEntry.cxx
-//-----------------------------------------------------------------------------
-//
+/*=========================================================================
+                                                                                
+  Program:   gdcm
+  Module:    $RCSfile: gdcmDocEntry.cxx,v $
+  Language:  C++
+  Date:      $Date: 2004/07/02 13:55:27 $
+  Version:   $Revision: 1.13 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See Doc/License.txt or
+  http://www.creatis.insa-lyon.fr/Public/Gdcm/License.htm for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
 
 #include "gdcmDocEntry.h"
 #include "gdcmTS.h"
@@ -24,20 +38,14 @@ gdcmDocEntry::gdcmDocEntry(gdcmDictEntry* in) {
    entry = in;
 }
 
-void gdcmDocEntry::Print(std::ostream & os) {
-   std::ostringstream s;
-   s << std::endl;
-   PrintCommonPart(os);
-   os << s.str();
-}
-
 //-----------------------------------------------------------------------------
 // Print
 /**
  * \ingroup gdcmDocEntry
  * \brief   Prints the common part of gdcmValEntry, gdcmBinEntry, gdcmSeqEntry
+ * @param   os ostream we want to print in
  */
-void gdcmDocEntry::PrintCommonPart(std::ostream & os) {
+void gdcmDocEntry::Print(std::ostream & os) {
 
    printLevel=2; // FIXME
    
@@ -47,7 +55,7 @@ void gdcmDocEntry::PrintCommonPart(std::ostream & os) {
    TSKey v;
    std::string d2, vr;
    std::ostringstream s;
-   guint32 lgth;
+   uint32_t lgth;
    char greltag[10];  //group element tag
 
    g  = GetGroup();
@@ -93,6 +101,85 @@ void gdcmDocEntry::PrintCommonPart(std::ostream & os) {
    os << s.str();      
 }
 
+/**
+ * \ingroup gdcmDocEntry
+ * \brief   Writes the common part of any gdcmValEntry, gdcmBinEntry, gdcmSeqEntry
+ */
+void gdcmDocEntry::Write(FILE *fp, FileType filetype) {
+
+   uint32_t FFFF  = 0xffffffff;
+   uint16_t group = GetGroup();
+   gdcmVRKey vr   = GetVR();
+   uint16_t el    = GetElement();
+   uint32_t lgr   = GetReadLength();
+
+   if ( (group == 0xfffe) && (el == 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; 
+
+//
+// ----------- Writes the common part
+//
+   fwrite ( &group,(size_t)2 ,(size_t)1 ,fp);  //group
+   fwrite ( &el,   (size_t)2 ,(size_t)1 ,fp);  //element
+      
+   if ( filetype == gdcmExplicitVR ) {
+
+      // Special case of delimiters:
+      if (group == 0xfffe) {
+         // Delimiters have NO Value Representation
+         // Hence we skip writing the VR.
+         // In order to avoid further troubles, we choose to write them
+         // as 'no-length' Item Delimitors (we pad by writing 0xffffffff)
+         // The end of a given Item will be found when  :
+         //  - a new Item Delimitor Item is encountered (the Seq goes on)
+         //  - a Sequence Delimitor Item is encountered (the Seq just ended)
+
+       // TODO : verify if the Sequence Delimitor Item was forced during Parsing 
+
+         int ff=0xffffffff;
+         fwrite (&ff,(size_t)4 ,(size_t)1 ,fp);
+         return;
+      }
+
+      uint16_t z=0;
+      uint16_t shortLgr = lgr;
+
+      if (vr == "unkn") {     // Unknown was 'written'
+         // deal with Little Endian            
+         fwrite ( &shortLgr,(size_t)2 ,(size_t)1 ,fp);
+         fwrite ( &z,  (size_t)2 ,(size_t)1 ,fp);
+      } else {
+         fwrite (vr.c_str(),(size_t)2 ,(size_t)1 ,fp); 
+                  
+         if ( (vr == "OB") || (vr == "OW") || (vr == "SQ") || (vr == "UN") )
+         {
+            fwrite ( &z,  (size_t)2 ,(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);
+         }
+      }
+   } 
+   else // IMPLICIT VR 
+   { 
+      if (vr == "SQ") {
+          fwrite ( &FFFF,(size_t)4 ,(size_t)1 ,fp);
+       } else {
+          fwrite ( &lgr,(size_t)4 ,(size_t)1 ,fp);
+       }
+   }
+}
+
 //-----------------------------------------------------------------------------
 // Public
 
@@ -100,8 +187,8 @@ void gdcmDocEntry::PrintCommonPart(std::ostream & os) {
  * \ingroup gdcmDocEntry
  * \brief   Gets the full length of the elementary DocEntry (not only value length)
  */
-guint32 gdcmDocEntry::GetFullLength(void) {
-   guint32 l;
+uint32_t gdcmDocEntry::GetFullLength(void) {
+   uint32_t l;
    l = GetReadLength();
    if ( IsImplicitVR() ) 
       l = l + 8;  // 2 (gr) + 2 (el) + 4 (lgth) 
@@ -117,7 +204,6 @@ guint32 gdcmDocEntry::GetFullLength(void) {
  * \ingroup gdcmDocEntry
  * \brief   Copies all the attributes from an other DocEntry 
  */
-
 void gdcmDocEntry::Copy (gdcmDocEntry* e) {
    this->entry        = e->entry;
    this->UsableLength = e->UsableLength;
@@ -128,13 +214,22 @@ void gdcmDocEntry::Copy (gdcmDocEntry* e) {
    // TODO : remove gdcmDocEntry SQDepth
 }
 
+/**
+ * \ingroup gdcmDocEntry
+ * \brief   tells us if entry is the last one of a 'no length' SequenceItem 
+ *          (fffe,e00d) 
+ */
 bool gdcmDocEntry::isItemDelimitor() {
    if ( (GetGroup() == 0xfffe) && (GetElement() == 0xe00d) )
       return true;
    else
       return false;      
 }
-
+/**
+ * \ingroup gdcmDocEntry
+ * \brief   tells us if entry is the last one of a 'no length' Sequence 
+ *          (fffe,e0dd) 
+ */
 bool gdcmDocEntry::isSequenceDelimitor() {
    if (GetGroup() == 0xfffe && GetElement() == 0xe0dd)
       return true;