]> Creatis software - gdcm.git/blobdiff - src/gdcmElValSet.cxx
* src/gdcmHeader.cxx gdcmHeader::gdcmHeader now calls LoadElements(),
[gdcm.git] / src / gdcmElValSet.cxx
index 6c140ae11eac05b9ac122a172d0497d1ee198bbb..094974503232cc230538aa109c08c5b4ddc2fa26 100644 (file)
@@ -1,22 +1,40 @@
-// $Header: /cvs/public/gdcm/src/Attic/gdcmElValSet.cxx,v 1.17 2003/03/12 21:33:20 frog Exp $
+// gdcmElValSet.cxx
 
+#include <sstream>
 #include "gdcmUtil.h"
 #include "gdcmElValSet.h"
 
 
-#include <vector>
-static void Tokenize (const string& str, vector<string>& tokens, const string& delimiters = " ");
-
-
 TagElValueHT & gdcmElValSet::GetTagHt(void) {
        return tagHt;
 }
 
 void gdcmElValSet::Add(gdcmElValue * newElValue) {
+   cout << "#### gdcmElValSet::Add" << newElValue->GetKey() << newElValue->GetName() << endl;
        tagHt [newElValue->GetKey()]  = newElValue;
        NameHt[newElValue->GetName()] = newElValue;
 }
 
+// TODO : faire un gdcmElValSet::ReplaceOrCreate qui remplace si ça existe, qui cree sinon
+
+void gdcmElValSet::ReplaceOrCreate(gdcmElValue * newElValue) {
+
+       TagKey key = newElValue->GetKey();
+
+       if (tagHt.count(key) > 1)
+               dbg.Verbose(0, "gdcmElValSet::GetElValueByNumber",
+                           "multiple entries for this key (FIXME) !");
+                           
+       if (tagHt.count(key)) {
+               tagHt.erase(key);
+               tagHt.erase(newElValue->GetName());
+       }
+
+       tagHt [key]                   = newElValue;
+       NameHt[newElValue->GetName()] = newElValue;
+}
+
+
 void gdcmElValSet::Print(ostream & os) {
        for (TagElValueHT::iterator tag = tagHt.begin();
                  tag != tagHt.end();
@@ -24,7 +42,9 @@ void gdcmElValSet::Print(ostream & os) {
                os << tag->first << ": ";
                os << "[" << tag->second->GetValue() << "]";
                os << "[" << tag->second->GetName()  << "]";
-               os << "[" << tag->second->GetVR()    << "]" << endl;
+               os << "[" << tag->second->GetVR()    << "]"; 
+               os << " lgr : " << tag->second->GetLength();
+                                               os << endl;
        }
 } 
 
@@ -111,6 +131,23 @@ int gdcmElValSet::SetElValueByName(string content, string TagName) {
        return(1);              
 }
 
+/**
+ * \ingroup  gdcmElValSet
+ * \brief    Generate a free TagKey i.e. a TagKey that is not present
+ *           in the TagHt dictionary. One of the potential usage is
+ *           to add  gdcm generated additional informartion to the ElValSet
+ *           (see gdcmHeader::AddAndDefaultElements).
+ * @param group The generated tag must belong to this group.  
+ * @return   The element of tag with given group which is fee.
+ */
+guint32 gdcmElValSet::GenerateFreeTagKeyInGroup(guint32 group) {
+   for (guint32 elem = 0; elem < UINT32_MAX; elem++) {
+      TagKey key = gdcmDictEntry::TranslateToKey(group, elem);
+      if (tagHt.count(key) == 0)
+         return elem;
+   }
+   return UINT32_MAX;
+}
 
 int gdcmElValSet::SetElValueLengthByNumber(guint32 l,
                                            guint32 group, guint32 element) {
@@ -122,8 +159,6 @@ int gdcmElValSet::SetElValueLengthByNumber(guint32 l,
                            "multiple entries for this key (FIXME) !");
                return (0); 
        }                                      
-   // FIXME JPR: comments in English please !
-       // m à j LgrElem 
        tagHt[key]->SetLength(l);        
        return(1);              
 }
@@ -141,6 +176,8 @@ int gdcmElValSet::SetElValueLengthByName(guint32 l, string TagName) {
        return(1);              
 }
 
+// Sorry for the DEBUG's, but tomorow is gonna be hoter than today
+#define DEBUG 0
 
 int gdcmElValSet::Write(FILE * _fp) {
 
@@ -153,17 +190,18 @@ int gdcmElValSet::Write(FILE * _fp) {
        guint32 val_uint32;
        gint32  val_int32;
        guint16 val_uint16;
-       gint16  val_int16;
+       gint16  val_int16;;
        
        vector<string> tokens;
        
        void *ptr;
        char str_lgrCalcGroupe[10];
+
        
        string implicitVRTransfertSyntax = "1.2.840.10008.1.2";
        
        // Utilisées pour le calcul Group Length
-       int deja = 0;
+       int deja = 0, prem=0;
        guint32 lgrCalcGroupe=0;
        gdcmElValue *elem, *elemZ, *elemZPrec;
        guint16 grCourant = 0;
@@ -179,60 +217,77 @@ int gdcmElValSet::Write(FILE * _fp) {
        //
        // cf : code IdDcmWriteFile dans libido/src/dcmwrite.c
                
-       if (0)  // Risque de pb dans le calcul des lgr de chaque groupe. On le saute pour le moment!
+if (1) {  // Risque de pb dans le calcul des lgr de chaque groupe. On le saute pour le moment!
+               
+       // On fait de l'implicit VR little Endian 
+       // (pour moins se fairche sur processeur INTEL)
+       // On force le TRANSFERT SYNTAX UID
+                               
+       SetElValueByNumber(implicitVRTransfertSyntax, 0x0002, 0x0010);  
+       SetElValueLengthByNumber(18, 0x0002, 0x0010);  // Le 0 de fin de chaine doit etre stocké, dans ce cas   
+                       
+       TagElValueHT::iterator tag = tagHt.begin();
        
-       for (TagElValueHT::iterator tag = tagHt.begin();
+       elem = tag->second;
+       gr   = elem->GetGroup();
+       el   = elem->GetElement();
+                       
+       if (el != 0x0000) {
+               if(DEBUG)printf("ajout elem OOOO premiere fois\n");
+               gdcmDictEntry * tagZ = new gdcmDictEntry(gr, 0x0000, "UL");
+               elemZPrec = new gdcmElValue(tagZ);      // on le cree
+               elemZPrec->SetLength(4);
+               Add(elemZPrec);                         // On l'accroche à sa place
+       } else {
+               elemZPrec = elem;
+               if(DEBUG)printf("Pas d'ajout elem OOOO premiere fois\n");
+       }
+       lgrCalcGroupe = 0;
+       if(DEBUG)printf("init-1 lgr (%d) pour gr %04x\n",lgrCalcGroupe, gr);
+       grCourant = gr;
+       
+       for (tag = ++tagHt.begin();
                  tag != tagHt.end();
                  ++tag){
-
+                 
                elem = tag->second;
-               printf("gr %04x el %04x lgr %d\n",elem->GetGroup(), elem->GetElement(), elem->GetLength());
-       
-               if ( (elem->GetGroup() != grCourant) &&   
-                        (elem->GetGroup() != 0xfffe)   ) {     // On arrive sur un nv Groupe
-                        
-               printf("Nouv Groupegr %04x el %04x \n",elem->GetGroup(), elem->GetElement());
-
-                       elemZ = elem; 
-                        
-                       if(elemZ->GetElement() != 0x0000) {     // pas d'element 'Lgr groupe'
-                               // On crée
-                               gdcmDictEntry * tagZ = new gdcmDictEntry(grCourant, 0x0000, "UL");
+               gr = elem->GetGroup();
+               el = elem->GetElement();
+
+               if ( (gr != grCourant) /*&&     // On arrive sur un nv Groupe     
+                    (el != 0xfffe) */  ) {
+                           
+                       if (el != 0x0000) {
+                               gdcmDictEntry * tagZ = new gdcmDictEntry(gr, 0x0000, "UL");
                                elemZ = new gdcmElValue(tagZ); // on le cree
                                elemZ->SetLength(4);
-                               Add(elemZ);                                      // On l'accroche à sa place    
-                       }       
-                       
-                       if (deja) {
-                               //sprintf(str_lgrCalcGroupe,"%d",lgrCalcGroupe);
-                               elemZPrec->SetValue(str_lgrCalcGroupe);
-                               lgrCalcGroupe = 0;
+                               Add(elemZ);                     // On l'accroche à sa place 
+                               if(DEBUG)printf("ajout elem OOOO pour gr %04x\n",gr);
+                       } else { 
+                               elemZ=elem;
+                               if(DEBUG)printf("maj elmeZ\n");
                        }
-                       deja = 1;
-                       
-                       lgrCalcGroupe =  12; //2 + 2 + 4 + 4; // Gr + Num + Lgr + LgrGroupe
-                       printf ("lgrCalcGroupe %d\n",lgrCalcGroupe);
                        
-                       elemZPrec = elemZ;
-                       grCourant = elem->GetGroup();
-                                                       
-               } else {                // On n'EST PAS sur un nv Groupe
-               
-                       printf ("lgrCalcGroupe avant : %d LgrElem %d\n",lgrCalcGroupe,elem->GetLength());
-
-                       lgrCalcGroupe += 2 + 2 + 4 + elem->GetLength();  // Gr + Num + Lgr + LgrElem 
-                       
-                       printf ("lgrCalcGroupe apres %d\n",lgrCalcGroupe);
+                       ostringstream fock;
+                       fock << lgrCalcGroupe; 
+                       //sprintf(str_lgrCalcGroupe,"%d",lgrCalcGroupe);
+                       elemZPrec->SetValue(fock.str());
+                       if(DEBUG)printf("ecriture lgr (%d, %s) pour gr %04x\n",lgrCalcGroupe, fock.str().c_str(), grCourant);
+                       if(DEBUG)printf ("%04x %04x [%s]\n",elemZPrec->GetGroup(), elemZPrec->GetElement(),elemZPrec->GetValue().c_str());
+                       if(DEBUG)cout << "Addresse elemZPrec " << elemZPrec<< endl;
+                       elemZPrec=elemZ;
+                       lgrCalcGroupe = 0;
+                       grCourant     = gr;     
+                       if(DEBUG)printf("init-2 lgr (%d) pour gr %04x\n",lgrCalcGroupe, gr);                    
+               } else {                        // On n'EST PAS sur un nv Groupe
+                       lgrCalcGroupe += 2 + 2 + 4 + elem->GetLength();  // Gr + Num + Lgr + LgrElem
+                       if(DEBUG)printf("increment (%d) el %04x-->lgr (%d) pour gr %04x\n",elem->GetLength(), el, lgrCalcGroupe, gr);
                }               
        }
        
-       // Si on fait de l'implicit VR little Endian 
-       // (pour moins se fairche sur processeur INTEL)
-       // penser a forcer le TRANSFERT SYNTAX UID
-                               
-       SetElValueByNumber(implicitVRTransfertSyntax, 0x0002, 0x0010);  
-       SetElValueLengthByNumber(18, 0x0002, 0x0010);  // Le 0 de fin de chaine doit etre stocké, dans ce cas   
-               
+} // fin if (1)
+
+       
        // restent à tester les echecs en écriture (apres chaque fwrite)
        
        for (TagElValueHT::iterator tag2 = tagHt.begin();
@@ -244,6 +299,7 @@ int gdcmElValSet::Write(FILE * _fp) {
                lgr = tag2->second->GetLength();
                val = tag2->second->GetValue().c_str();
                vr =  tag2->second->GetVR();
+               if(DEBUG)printf ("%04x %04x [%s] : [%s]\n",gr, el, vr.c_str(), val);
                        
                fwrite ( &gr,(size_t)2 ,(size_t)1 ,_fp);        //group
                fwrite ( &el,(size_t)2 ,(size_t)1 ,_fp);        //element
@@ -252,47 +308,28 @@ int gdcmElValSet::Write(FILE * _fp) {
                
                // si on n'est pas en IMPLICIT VR voir pb (lgr  + VR)
                
-               fwrite ( &lgr,(size_t)4 ,(size_t)1 ,_fp);               //lgr
+               fwrite ( &lgr,(size_t)4 ,(size_t)1 ,_fp);       //lgr
                
                tokens.erase(tokens.begin(),tokens.end());
                Tokenize (tag2->second->GetValue(), tokens, "\\");
                
-               //printf ("%04x %04x [%s] : [%s]\n",gr, el, vr.c_str(), val);
                //if (tokens.size() > 1) { printf ("size : %d\n",tokens.size());}
                
-               
                if (vr == "US" || vr == "SS") {
-                       /*
-                       val_int16 = atoi(val);
-                       ptr = &val_int16;
-                       fwrite ( ptr,(size_t)2 ,(size_t)1 ,_fp);        
-                       continue;
-                       */
-                       
                        for (unsigned int i=0; i<tokens.size();i++) {
                                val_uint16 = atoi(tokens[i].c_str());           
                                ptr = &val_uint16;
                                fwrite ( ptr,(size_t)2 ,(size_t)1 ,_fp);
                        }
-                       continue;
-                       
+                       continue;       
                }
-               if (vr == "UL" || vr == "SL") {
-                       /*
-                       val_int32 = atoi(val);
-                       ptr = &val_int32;
-                       fwrite ( ptr,(size_t)4 ,(size_t)1 ,_fp);        
-                       continue;
-                       */
-                       
-                       
+               if (vr == "UL" || vr == "SL") { 
                        for (unsigned int i=0; i<tokens.size();i++) {
                                val_uint32 = atoi(tokens[i].c_str());           
                                ptr = &val_uint32;
                                fwrite ( ptr,(size_t)4 ,(size_t)1 ,_fp);
                        }
-                       continue;                               
-                       
+                       continue;       
                }       
                
                // Les pixels ne sont pas chargés dans l'element !
@@ -347,50 +384,64 @@ int gdcmElValSet::WriteAcr(FILE * _fp) {
        //
        // cf : code IdDcmWriteFile dans libido/src/dcmwrite.c
                
-       if (1)  // Risque de pb dans le calcul des lgr de chaque groupe. On le saute pour le moment!
+
+                       
+       TagElValueHT::iterator tag = tagHt.begin();
        
-       for (TagElValueHT::iterator tag = tagHt.begin();
+       elem = tag->second;
+       gr   = elem->GetGroup();
+       el   = elem->GetElement();
+                       
+       if (el != 0x0000) {
+               if(DEBUG)printf("ajout elem OOOO premiere fois\n");
+               gdcmDictEntry * tagZ = new gdcmDictEntry(gr, 0x0000, "UL");
+               elemZPrec = new gdcmElValue(tagZ);      // on le cree
+               elemZPrec->SetLength(4);
+               Add(elemZPrec);                         // On l'accroche à sa place
+       } else {
+               elemZPrec = elem;
+               if(DEBUG)printf("Pas d'ajout elem OOOO premiere fois\n");
+       }
+       lgrCalcGroupe = 0;
+       if(DEBUG)printf("init-1 lgr (%d) pour gr %04x\n",lgrCalcGroupe, gr);
+       grCourant = gr;
+       
+       for (tag = ++tagHt.begin();
                  tag != tagHt.end();
                  ++tag){
-
+                 
                elem = tag->second;
-               //printf("gr %04x el %04x lgr %d\n",elem->GetGroup(), elem->GetElement(), elem->GetLength());
-       
-               if ( (elem->GetGroup() != grCourant) &&   
-                        (elem->GetGroup() != 0xfffe)   ) {     // On arrive sur un nv Groupe
-                        
-               //printf("Nouv Groupegr %04x el %04x \n",elem->GetGroup(), elem->GetElement());
-
-                       elemZ = elem; 
-                        
-                       if(elemZ->GetElement() != 0x0000) {     // pas d'element 'Lgr groupe'
-                               // On crée
-                               gdcmDictEntry * tagZ = new gdcmDictEntry(grCourant, 0x0000, "UL");
+               gr = elem->GetGroup();
+               el = elem->GetElement();
+
+               if ( (gr != grCourant) /*&&     // On arrive sur un nv Groupe     
+                    (el != 0xfffe) */  ) {
+                           
+                       if (el != 0x0000) {
+                               gdcmDictEntry * tagZ = new gdcmDictEntry(gr, 0x0000, "UL");
                                elemZ = new gdcmElValue(tagZ); // on le cree
                                elemZ->SetLength(4);
-                               Add(elemZ);                                      // On l'accroche à sa place    
-                       }       
-                       
-                       if (deja) {
-                               //sprintf(str_lgrCalcGroupe,"%d",lgrCalcGroupe);
-                               elemZPrec->SetValue(str_lgrCalcGroupe);
-                               lgrCalcGroupe = 0;
+                               Add(elemZ);                     // On l'accroche à sa place 
+                               if(DEBUG)printf("ajout elem OOOO pour gr %04x\n",gr);
+                       } else { 
+                               elemZ=elem;
+                               if(DEBUG)printf("maj elmeZ\n");
                        }
-                       deja = 1;
                        
-                       lgrCalcGroupe =  12; //2 + 2 + 4 + 4; // Gr + Num + Lgr + LgrGroupe
-                       //printf ("lgrCalcGroupe %d\n",lgrCalcGroupe);
-                       
-                       elemZPrec = elemZ;
-                       grCourant = elem->GetGroup();
-                                                       
-               } else {                // On n'EST PAS sur un nv Groupe
-               
-                       //printf ("lgrCalcGroupe avant : %d LgrElem %d\n",lgrCalcGroupe,elem->GetLength());
-
-                       lgrCalcGroupe += 2 + 2 + 4 + elem->GetLength();  // Gr + Num + Lgr + LgrElem 
-                       
-                       //printf ("lgrCalcGroupe apres %d\n",lgrCalcGroupe);
+                       ostringstream fock;
+                       fock << lgrCalcGroupe; 
+                       //sprintf(str_lgrCalcGroupe,"%d",lgrCalcGroupe);
+                       elemZPrec->SetValue(fock.str());
+                       if(DEBUG)printf("ecriture lgr (%d, %s) pour gr %04x\n",lgrCalcGroupe, fock.str().c_str(), grCourant);
+                       if(DEBUG)printf ("%04x %04x [%s]\n",elemZPrec->GetGroup(), elemZPrec->GetElement(),elemZPrec->GetValue().c_str());
+                       if(DEBUG)cout << "Addresse elemZPrec " << elemZPrec<< endl;
+                       elemZPrec=elemZ;
+                       lgrCalcGroupe = 0;
+                       grCourant     = gr;     
+                       if(DEBUG)printf("init-2 lgr (%d) pour gr %04x\n",lgrCalcGroupe, gr);                    
+               } else {                        // On n'EST PAS sur un nv Groupe
+                       lgrCalcGroupe += 2 + 2 + 4 + elem->GetLength();  // Gr + Num + Lgr + LgrElem
+                       if(DEBUG)printf("increment (%d) el %04x-->lgr (%d) pour gr %04x\n",elem->GetLength(), el, lgrCalcGroupe, gr);
                }               
        }
        
@@ -457,19 +508,3 @@ int gdcmElValSet::WriteAcr(FILE * _fp) {
                
        return(1);
 }
-
-
-
-
-// mettre ça dans une bibliothèque d'utilitaires ?
-// ca peut servir
-
-static void Tokenize (const string& str, vector<string>& tokens, const string& delimiters = " ") {
-       string::size_type lastPos = str.find_first_not_of(delimiters,0);
-       string::size_type pos     = str.find_first_of(delimiters,lastPos);
-       while (string::npos != pos || string::npos != lastPos) {
-               tokens.push_back(str.substr(lastPos, pos - lastPos));
-               lastPos = str.find_first_not_of(delimiters, pos);
-               pos = str.find_first_of(delimiters, lastPos);
-       }
-}