]> Creatis software - gdcm.git/commitdiff
Ajout fonctions
authorjpr <jpr>
Tue, 14 Jan 2003 13:23:48 +0000 (13:23 +0000)
committerjpr <jpr>
Tue, 14 Jan 2003 13:23:48 +0000 (13:23 +0000)
int AddNewEntry (gdcmDictEntry* NewEntry);
int ReplaceEntry(gdcmDictEntry* NewEntry);
int RemoveEntry (TagKey k);
int RemoveEntry (guint16 group, guint16 element);

src/gdcm.h
src/gdcmDict.cxx
src/gdcmDictEntry.cxx
src/gdcmElValSet.cxx
src/gdcmElValue.cxx
src/gdcmFile.cxx

index 36ddb3df8918e1ceb370c107b3cbcba4b7e02c76..457920c493cfc31dbf165da9e17278d4087a54e4 100644 (file)
@@ -52,7 +52,6 @@ using namespace std;  // string type lives in the std namespace on VC++
                       // exporter des images lisibles par les consoles cliniques 
                       // et pas seulement importables dans e-film. 
 
-
 #ifdef __GNUC__
 #include <stdint.h>
 #define guint16 uint16_t
@@ -70,7 +69,6 @@ typedef  unsigned int   guint32;
 #define GDCM_EXPORT
 #endif
 
-
 //
 // ---------------------------------------------------- gdcmDictEntry
 //
@@ -133,6 +131,7 @@ public:
        guint16 GetElement(void){return element;};
        string  GetVR(void)     {return vr;     };
        void    SetVR(string);
+       void    SetKey(string k){ key = k;              }
        bool    IsVrUnknown(void);
        string  GetFourth(void) {return fourth;};
        string  GetName(void)   {return name;  };
@@ -154,8 +153,6 @@ public:
 typedef map<TagKey, gdcmDictEntry*> TagHT;
        // Table de Hachage : (group,Elem) --> pointeur vers une ligne du Dictionnaire Dicom
 
-typedef map<TagKey, gdcmDictEntry*> TagHT;
-
 class GDCM_EXPORT gdcmDict {
        string name;
        string filename;
@@ -164,10 +161,11 @@ public:
        // rempli le Dictionnaire Dicom à partir d'un fichier texte
        gdcmDict(const char* FileName);   // Read Dict from disk
        
-       // QUESTION :
-       // Ca doit ajouter une nouvelle entrée 'a la fin', ou 'a sa place' ?
-       //
-       // TODO Swig int AppendEntry(gdcmDictEntry* NewEntry);
+       int AddNewEntry (gdcmDictEntry* NewEntry);
+       int ReplaceEntry(gdcmDictEntry* NewEntry);
+       int RemoveEntry (TagKey k);
+       int RemoveEntry (guint16 group, guint16 element);
+
        
        // renvoie une ligne de Dictionnaire Dicom à partir de (numGroup, numElement)
        gdcmDictEntry * GetTag(guint32 group, guint32 element);
@@ -253,25 +251,36 @@ private:
 public:
        string  value;     // used to be char * valeurElem
        size_t Offset;     // Offset from the begining of file for direct user access
+       
        ElValue(gdcmDictEntry*);
        void SetDictEntry(gdcmDictEntry *NewEntry) { entry = NewEntry; };
-
        bool   IsVrUnknown(void) { return entry->IsVrUnknown(); };
-       
-       void SetLength(guint32 l){ LgrElem = l; };
-       void SetValue(string val){ value = val; };
-       void SetOffset(size_t of){ Offset = of; };
        void SetImplicitVr(void) { ImplicitVr = true; };
        bool  IsImplicitVr(void) { return ImplicitVr; };
-       void    SetVR(string);
-       string  GetVR(void);
-       string  GetValue(void)   { return value;               };
-       guint32 GetLength(void)  { return LgrElem;             };
-       size_t  GetOffset(void)  { return Offset;              };
-       guint16 GetGroup(void)   { return entry->GetGroup();   };
+
+       guint16 GetGroup(void)   { return entry->GetGroup();   };       
        guint16 GetElement(void) { return entry->GetElement(); };
        string  GetKey(void)     { return entry->GetKey();     };
        string  GetName(void)    { return entry->GetName();    };
+       
+       string  GetVR(void)              { return entry->GetVR(); };
+       
+       void    SetVR(string v)  { entry->SetVR(v);       }; 
+               
+       // Question :
+       // Un champ privé, accessible en consultation et en modif (sans restriction)
+       // interet par rapport à un champ public ? 
+       // --> pouvoir en changer la définition sans toucher à l'API
+       
+       void SetLength(guint32 l){ LgrElem = l;         };
+       guint32 GetLength(void)  { return LgrElem;      };
+
+       void SetValue(string val){ value = val;         };
+       string  GetValue(void)   { return value;        };
+
+       void SetOffset(size_t of){ Offset = of;         };
+       size_t  GetOffset(void)  { return Offset;       };      
+
 };
 
 
@@ -300,7 +309,8 @@ public:
        ElValue* GetElementByName  (string);
        string   GetElValueByNumber(guint32 group, guint32 element);
        string   GetElValueByName  (string);
-       TagElValueHT & GetTagHt(void);
+       
+       TagElValueHT & GetTagHt(void);  
        
        int SetElValueByNumber(string content, guint32 group, guint32 element);
        int SetElValueByName(string content, string TagName);
@@ -328,24 +338,17 @@ public:
 //   (Swig limitations for as Has_a dependency between gdcmFile and gdcmHeader)
  
 
-typedef string VRKey;  // Ne devrait-elle pas etre utilisee dans la definition de VRHT ?
+typedef string VRKey;
 typedef string VRAtr;
-typedef map<TagKey, VRAtr> VRHT;    // Value Representation Hash Table
-               // Cette Table de Hachage ne devrait servir qu'a determiner
-               // si deux caractères correspondent à une VR existante ?        
+typedef map<VRKey, VRAtr> VRHT;    // Value Representation Hash Table
+
 
 class GDCM_EXPORT gdcmHeader {
        void SkipBytes(guint32);
 private:
        static VRHT *dicom_vr;
        // Dictionaries of data elements:
-       
-       // Question :
-       // Pourquoi mettre un pointeur statique vers le container des dictionnaires
-       // (qui est une H-table de pointeurs vers des dictionnaires)
-       // en plus des pointeurs vers chacun des dictionnaires ?
-       // Ces derniers n'auraient-ils pas suffit ?
-       //
+
        static gdcmDictSet* Dicts;  // global dictionary container
        gdcmDict* RefPubDict;       // public dictionary
        gdcmDict* RefShaDict;       // shadow dictionary (optional)
@@ -560,6 +563,12 @@ public:
        
        int PutImageDataHere(void* destination, size_t MaxSize );
        
+       // Question :
+       //
+       //      GetImageData et PutImageDataHere
+       // Get et Put pour 2 fonctions qui font presque la meme chose :-(
+       //
+       
        // Allocates ExpectedSize bytes of memory at this->Data and copies the
        // pointed data to it.
        
index 32cc12467410975dd91ebb1ae9c0f8dd8fa22977..da9423b899341d5c4810826dbd5dd97acc12cef1 100644 (file)
@@ -50,3 +50,65 @@ gdcmDictEntry * gdcmDict::GetTag(guint32 group, guint32 element) {
                            "multiple entries for this key (FIXME) !");
        return entries.find(key)->second;
 }
+
+
+int gdcmDict::ReplaceEntry(gdcmDictEntry* NewEntry) {
+
+       // au cas ou la NewEntry serait incomplete
+       // Question : cela peut-il se produire ?
+       //
+       TagKey key;
+       key = NewEntry->GetKey();
+       if (key =="") {
+               NewEntry->gdcmDictEntry::SetKey(
+                               gdcmDictEntry::TranslateToKey(NewEntry->GetGroup(), NewEntry->GetElement())
+                               );
+       }
+       
+       entries.erase (NewEntry->gdcmDictEntry::GetKey());
+       entries[ NewEntry->GetKey()] = NewEntry;
+       return (1);
+       // Question : Dans quel cas ça peut planter ?
+}
+
+int gdcmDict::AddNewEntry(gdcmDictEntry* NewEntry) {
+
+       // au cas ou la NewEntry serait incomplete
+       // Question : cela peut-il se produire ?
+       //
+       
+       TagKey key;
+       key = NewEntry->GetKey();
+       if (key =="") {
+               NewEntry->SetKey(
+                               gdcmDictEntry::TranslateToKey(NewEntry->GetGroup(), NewEntry->GetElement())
+                               );
+       }
+
+       if(entries.count(key) >= 1) {
+               printf("gdcmDict::AddNewEntry %s deja present\n", key.c_str());
+               return(0);
+       } else {
+               entries[NewEntry->GetKey()] = NewEntry;
+               return(1);
+       }
+       }
+
+
+int gdcmDict::RemoveEntry(TagKey key) {        
+       if(entries.count(key) == 1) {
+               entries.erase(key);
+               return (1);
+       } else {
+               printf("gdcmDict::RemoveEntry %s non trouve\n", key.c_str());
+               return (0);
+       }
+}
+
+
+int gdcmDict::RemoveEntry (guint16 group, guint16 element) {
+
+       return( RemoveEntry(gdcmDictEntry::TranslateToKey(group, element)) );
+}
+
index c9b1ca0c687943e563402b8ce861d2818e3257f3..3e9b109e14cc6bc80bd31866554c08cbfb6357b1 100644 (file)
@@ -6,12 +6,12 @@
 gdcmDictEntry::gdcmDictEntry(guint16 InGroup, guint16 InElement,
                              string  InVr, string InFourth, string InName) 
 {
-       group = InGroup;
-       element = InElement;
-       vr = InVr;
-       fourth = InFourth;
-       name = InName;
-       key = TranslateToKey(group, element);
+       group           = InGroup;
+       element         = InElement;
+       vr              = InVr;
+       fourth          = InFourth;
+       name            = InName;
+       key             = TranslateToKey(group, element);
 }
 
 TagKey gdcmDictEntry::TranslateToKey(guint16 group, guint16 element) {
index 70f21fc15ffc47f8ae25538ca06f97651e3aee99..6cdcc310cac9d592d7d9ac2e8afe76a85f526965 100644 (file)
@@ -22,14 +22,32 @@ void ElValSet::Print(ostream & os) {
                os << "[" << tag->second->GetVR()    << "]" << endl;
        }
 }
-
 
 int ElValSet::Write(FILE * _fp) {
 
+// ATTENTION : fonction non terminée (commitée a titre de precaution)
+
        guint16 gr, el;
        guint32 lgr;
        const char * val;
-       // restent à tester les echecs en écriture
+       
+       // A FAIRE :
+       // parcourir la table pour recalculer la longueur des 'elements 0x0000'
+       // au cas ou un tag ai été ajouté par rapport à ce qui a été lu
+       // dans l'image native
+       //
+       // cf : code IdDcmWriteFile
+       
+/*     
+       for (TagElValueHT::iterator tag = tagHt.begin();
+                 tag != tagHt.end();
+                 ++tag){
+
+
+       }
+*/
+       // resteront à tester les echecs en écriture
        for (TagElValueHT::iterator tag = tagHt.begin();
                  tag != tagHt.end();
                  ++tag){
@@ -38,29 +56,37 @@ int ElValSet::Write(FILE * _fp) {
                // peut-on se passer des affectations?
                // - passer l'adresse du resultat d'une fonction (???)
                // - acceder au champ sans passer par un accesseur ?
-               gr = tag->second->GetGroup();
-               el = tag->second->GetElement();
+               gr =  tag->second->GetGroup();
+               el =  tag->second->GetElement();
                lgr = tag->second->GetLength();
                val = tag->second->GetValue().c_str();
                
                fwrite ( &gr,(size_t)2 ,(size_t)1 ,_fp);        //group
                fwrite ( &el,(size_t)2 ,(size_t)1 ,_fp);        //element
-               //fwrite ( tag->second->GetVR(),(size_t)2 ,(size_t)1 ,_fp);     //VR
                
+               //fwrite ( tag->second->GetVR(),(size_t)2 ,(size_t)1 ,_fp);     //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
+                
+               // ATTENTION
                // voir pb des int16 et int32 : les identifier, les convertir, modifier la longueur
+               // ou alors stocker la valeur 16 ou 32 bits, + un indicateur : char, int16, int32
+               
                fwrite ( val,(size_t)lgr ,(size_t)1 ,_fp); //valeur Elem
        }
        return(1);
 }
+
+
+
 void ElValSet::PrintByName(ostream & os) {
        for (TagElValueNameHT::iterator tag = NameHt.begin();
                  tag != NameHt.end();
                  ++tag){
                os << tag->first << ": ";
                os << "[" << tag->second->GetValue() << "]";
-               os << "[" << tag->second->GetKey()  << "]";
+               os << "[" << tag->second->GetKey()   << "]";
                os << "[" << tag->second->GetVR()    << "]" << endl;
        }
 }
index 060ffb99eb767cb911d69a9fe936f0fbb43abc8d..339069021ba1525f4766c6eb402c6279eaeeb44e 100644 (file)
@@ -2,10 +2,11 @@
 
 #include "gdcm.h"
 
-void   ElValue::SetVR(string ValRep) { entry->SetVR(ValRep); }
-string ElValue::GetVR(void)          { return entry->GetVR(); }
+       // void    ElValue::SetVR(string v)      { entry->SetVR(v);       };
 
 ElValue::ElValue(gdcmDictEntry* in) {
        ImplicitVr = false;
        entry = in;
 }
+
+
index 11f9b015aebae994137936a80914bb1a0b00d583..89c872f3cf81e0ae0608d02ffd9a972757a33114 100644 (file)
@@ -24,10 +24,9 @@ static void _Swap(void* im, int swap, int lgr, int nb);
  * @return     
  */
  
-gdcmFile::gdcmFile(string & filename)
-       :gdcmHeader(filename.c_str())
+gdcmFile::gdcmFile(string & filename) 
+       :gdcmHeader(filename.c_str())   
 {
-       if (DEBUG) printf("On a echappe a gdcmHeader !\n");
 }
 
 
@@ -52,10 +51,6 @@ size_t gdcmFile::GetImageDataSize(void) {
        // Nombre de Colonnes   
        nbCol   =atoi(gdcmHeader::GetPubElValByNumber(0x0028,0x0011).c_str());
 
-printf("nbCol %d\n",nbCol);
-printf("nbLig %d\n",nbLignes);
-
-
        // Nombre de Frames     
        str_nbFrames=gdcmHeader::GetPubElValByNumber(0x0028,0x0008);
        
@@ -64,7 +59,6 @@ printf("nbLig %d\n",nbLignes);
        } else {
                nbFrames = atoi(str_nbFrames.c_str() );
        }
-printf("nbFrames %d\n",nbFrames);
        
        // Nombre de Bits Alloues pour le stockage d'un Pixel   
        str_nb=gdcmHeader::GetPubElValByNumber(0x0028,0x0100);
@@ -75,8 +69,6 @@ printf("nbFrames %d\n",nbFrames);
                nb = atoi(str_nb.c_str() );
        }
 
-printf("nb %d\n",nb);
-
        size_t lgrTotale = nbFrames*nbLignes*nbCol*(nb/8);
        return (lgrTotale);
 
@@ -96,37 +88,21 @@ printf("nb %d\n",nb);
 void * gdcmFile::GetImageData (void) {
        
        char* _Pixels;
-       int nbLignes, nbCol;
 
-       int nbFrames, nb, nbu, highBit, signe;
+       int  nb, nbu, highBit, signe;
        string str_nbFrames, str_nb, str_nbu, str_highBit, str_signe;
        
        unsigned short int mask = 0xffff;
-               
-       // Nombre de Lignes     
-       nbLignes=atoi(GetPubElValByNumber(0x0028,0x0010).c_str());
-       // Nombre de Colonnes   
-       nbCol   =atoi(GetPubElValByNumber(0x0028,0x0011).c_str());
-
-       // Nombre de Frames     
-       str_nbFrames=GetPubElValByNumber(0x0028,0x0008);
 
-       
-       if (str_nbFrames == "gdcm::Unfound" ) {
-               nbFrames = 1;
-       } else {
-               nbFrames = atoi(str_nbFrames.c_str() );
-       }
-       
-       // Nombre de Bits Alloues       
-       str_nb=GetPubElValByNumber(0x0028,0x0100);
+       // Nombre de Bits Alloues pour le stockage d'un Pixel   
+       str_nb=gdcmHeader::GetPubElValByNumber(0x0028,0x0100);
 
        if (str_nb == "gdcm::Unfound" ) {
                nb = 16;
        } else {
                nb = atoi(str_nb.c_str() );
        }
-       
+                       
        // Nombre de Bits Utilises      
        str_nbu=GetPubElValByNumber(0x0028,0x0101);
 
@@ -155,7 +131,7 @@ void * gdcmFile::GetImageData (void) {
        }
        
        // Longueur en Octets des Pixels a lire
-       size_t _lgrTotale = nbFrames*nbLignes*nbCol*(nb/8);
+       size_t _lgrTotale = GetImageDataSize();
        
        //Pixels = (char *) g_malloc(_lgrTotale);
        _Pixels = (char *) malloc(_lgrTotale);
@@ -212,32 +188,33 @@ void * gdcmFile::GetImageData (void) {
  */
 
 int gdcmFile::PutImageDataHere (void* destination, size_t MaxSize) {
+
+// Question :
+//     dans quel cas la Maxize sert-elle a quelque chose?
+//     que fait-on si la taille de l'image est + gde    que Maxize?
+//     que fait-on si la taille de l'image est + petite que Maxize?
+
        
        void * Pixels = destination;  // pour garder le code identique avec GetImageData
-       int nbLignes, nbCol;
 
-       int nbFrames, nb, nbu, highBit, signe;
+       int nb, nbu, highBit, signe;
        string str_nbFrames, str_nb, str_nbu, str_highBit, str_signe;
        
        unsigned short int mask = 0xffff;
-               
-       // Nombre de Lignes     
-       nbLignes=atoi(GetPubElValByNumber(0x0028,0x0010).c_str());
-       // Nombre de Colonnes   
-       nbCol   =atoi(GetPubElValByNumber(0x0028,0x0011).c_str());
-
-       // Nombre de Frames     
-       str_nbFrames=GetPubElValByNumber(0x0028,0x0008);
-
        
-       if (str_nbFrames == "gdcm::Unfound" ) {
-               nbFrames = 1;
-       } else {
-               nbFrames = atoi(str_nbFrames.c_str() );
-       }
+       // Longueur en Octets des Pixels a lire
+       size_t _lgrTotale = GetImageDataSize(); // ne faudrait-il pas la stocker?
+       
+       // si lgrTotale < MaxSize ==> Gros pb . A VOIR
+       
+       lgrTotale = MaxSize;                                    // pour garder le code identique avec GetImageData
+       //Pixels = (char *) malloc(lgrTotale);  // pour garder le code identique avec GetImageData
        
-       // Nombre de Bits Alloues       
-       str_nb=GetPubElValByNumber(0x0028,0x0100);
+       GetPixels(lgrTotale, Pixels);
+               
+               
+       // Nombre de Bits Alloues pour le stockage d'un Pixel   
+       str_nb=gdcmHeader::GetPubElValByNumber(0x0028,0x0100);
 
        if (str_nb == "gdcm::Unfound" ) {
                nb = 16;
@@ -271,16 +248,7 @@ int gdcmFile::PutImageDataHere (void* destination, size_t MaxSize) {
        } else {
                signe = atoi(str_signe.c_str() );
        }
-       
-       // Longueur en Octets des Pixels a lire
-       size_t lgrTotale = nbFrames*nbLignes*nbCol*(nb/8);
-       
-       // si lgrTotale < MaxSize ==> Gros pb . A VOIR
-       
-       lgrTotale = MaxSize;                                    // pour garder le code identique avec GetImageData
-       //Pixels = (char *) malloc(lgrTotale);  // pour garder le code identique avec GetImageData
-       
-       GetPixels(lgrTotale, Pixels);
+
 
        // On remet les Octets dans le bon ordre si besoin est
        if (nb != 8) {
@@ -304,9 +272,7 @@ int gdcmFile::PutImageDataHere (void* destination, size_t MaxSize) {
                                deb ++;
                }
        }
-               
-       printf ("on est sorti\n");
-       
+                       
        // VOIR s'il ne faudrait pas l'affecter à un champ du dcmHeader
        
        //return (Pixels);                              // pour garder le code identique avec GetImageData      
@@ -388,9 +354,6 @@ if( nb == 32 )
 return;
 }
 
-
-
-
 /////////////////////////////////////////////////////////////////
 /**
  * \ingroup   gdcmFile
@@ -425,8 +388,8 @@ int gdcmFile::WriteRawData (string nomFichier) {
  * \ingroup   gdcmFile
  * \brief Ecrit sur disque UNE image Dicom
  * \Aucun test n'est fait sur l'"Endiannerie" du processeur.
- * \Ca sera à l'utilisateur d'appeler son Reader correctement
- * \ Equivalent a IdDcmWrite) 
+ * \Ca sera à l'utilisateur d'appeler son Reader correctement.
+ * \ (Equivalent a IdDcmWrite) 
  *
  * @param 
  *
@@ -447,13 +410,13 @@ int gdcmFile::WriteDcm (string nomFichier) {
        } 
        
        //      Ecriture Dicom File Preamble
-       //filePreamble=(char*)g_malloc0(128); // voir pourquoi ca ne passe pas a la compile
        filePreamble=(char*)calloc(128,1);
        fwrite(filePreamble,128,1,fp1);
        fwrite("DICM",4,1,fp1);
        if(DEBUG) printf("Ecriture File Preamble\n");
 
        // un accesseur de + est obligatoire ???
+       
        GetPubElVals().Write(fp1);
 
        fclose (fp1);