From: jpr Date: Fri, 10 Jan 2003 11:32:56 +0000 (+0000) Subject: ajout quelques fonctions pour WriteDcm X-Git-Tag: April2003~58 X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=commitdiff_plain;h=d0e0404925f8a3dc6f771ed598c75f9dea95912d;p=gdcm.git ajout quelques fonctions pour WriteDcm --- diff --git a/src/gdcm.h b/src/gdcm.h index d990d369..36ddb3df 100644 --- a/src/gdcm.h +++ b/src/gdcm.h @@ -119,7 +119,8 @@ public: // fabrique une ligne de Dictionnaire Dicom à partir des parametres en entrée - gdcmDictEntry(guint16 group, guint16 element, + gdcmDictEntry(guint16 group, + guint16 element, string vr = "Unknown", string fourth = "Unknown", string name = "Unknown"); @@ -128,14 +129,14 @@ public: static TagKey TranslateToKey(guint16 group, guint16 element); - guint16 GetGroup(void) { return group;}; + guint16 GetGroup(void) { return group; }; guint16 GetElement(void){return element;}; - string GetVR(void) {return vr; }; + string GetVR(void) {return vr; }; void SetVR(string); bool IsVrUnknown(void); string GetFourth(void) {return fourth;}; - string GetName(void) {return name;}; - string GetKey(void) {return key;}; + string GetName(void) {return name; }; + string GetKey(void) {return key; }; }; // @@ -151,7 +152,7 @@ public: // combined with all software versions... typedef map TagHT; - // Table de Hachage (group,Elem) --> pointeur vers une ligne du Dictionnaire Dicom + // Table de Hachage : (group,Elem) --> pointeur vers une ligne du Dictionnaire Dicom typedef map TagHT; @@ -212,6 +213,7 @@ public: // // Question : ne faudra-t-il pas mettre LE dictionnaire DICOM dans un Directory // et les eventuels 'dictionnaires prives' dans un autre? + // (pour eviter a un utilisateur mal dégourdi de tout saccager ?) // int LoadDicomV3Dict(void); void Print(ostream&); @@ -255,6 +257,7 @@ public: 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; }; @@ -292,6 +295,7 @@ public: void Add(ElValue*); void Print(ostream &); void PrintByName(ostream &); + int Write(FILE *fp); ElValue* GetElementByNumber(guint32 group, guint32 element); ElValue* GetElementByName (string); string GetElValueByNumber(guint32 group, guint32 element); @@ -350,8 +354,8 @@ private: ElValSet ShaElVals; // parsed with Shadow Dictionary string filename; // refering underlying file FILE * fp; - // The tag Image Location ((0028,0200) containing the address of - // the pixels) is not allways present. Then we store this information + // The tag Image Location (0028,0200) - containing the address of + // the pixels - is not allways present. Then we store this information // FIXME @@ -441,7 +445,7 @@ public: // TODO Swig int SetShaDict(string filename); // Retrieve all potentially available tag [tag = (group, element)] names - // from the standard (or public) dictionary. Typical usage: enable the + // from the standard (or public) dictionary. Typical usage : enable the // user of a GUI based interface to select his favorite fields for sorting // or selecting. list * GetPubTagNames(void); @@ -482,21 +486,22 @@ public: int SetShaElValByName(string content, string ShadowTagName); int SetShaElValByNumber(string content, guint16 group, guint16 element); + ElValSet GetPubElVals() { return(PubElVals); } }; // // ---------------------------------------------------- gdcmFile // // un fichier EST_UNE entete, ou A_UNE entete ? -// -// +// +// On dit 'EST_UNE' ... //////////////////////////////////////////////////////////////////////////// // In addition to Dicom header exploration, this class is designed // for accessing the image/volume content. One can also use it to // write Dicom files. -////// QUESTION: this looks still like an open question wether the +////// QUESTION: this looks still like an open question whether the ////// relationship between a gdcmFile and gdcmHeader is of ////// type IS_A or HAS_A ! @@ -557,7 +562,13 @@ public: // Allocates ExpectedSize bytes of memory at this->Data and copies the // pointed data to it. + + // Question : + // Pourquoi dupliquer les pixels, alors qu'on les a deja en mémoire, + // et que Data (dans le gdcmHeader) est un pointeur ? + // TODO Swig int SetImageData(void * Data, size_t ExpectedSize); + // Push to disk. // A NE PAS OUBLIER : que fait-on en cas de Transfert Syntax (dans l'entete) // incohérente avec l'ordre des octets en mémoire @@ -565,9 +576,10 @@ public: // Ecrit sur disque les pixels d'UNE image // Aucun test n'est fait sur l'"Endiannerie" du processeur. - // C'est à l'utilisateur d'appeler son Reader correctement + // Ca sera à l'utilisateur d'appeler son Reader correctement int WriteRawData (string nomFichier); + int WriteDcm (string nomFichier); }; // diff --git a/src/gdcmElValSet.cxx b/src/gdcmElValSet.cxx index 1f0760a4..70f21fc1 100644 --- a/src/gdcmElValSet.cxx +++ b/src/gdcmElValSet.cxx @@ -23,6 +23,37 @@ void ElValSet::Print(ostream & os) { } } + +int ElValSet::Write(FILE * _fp) { + + guint16 gr, el; + guint32 lgr; + const char * val; + // restent à tester les echecs en écriture + for (TagElValueHT::iterator tag = tagHt.begin(); + tag != tagHt.end(); + ++tag){ + + // Question : + // 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(); + 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 + + // voir pb lgr + VR + fwrite ( &lgr,(size_t)4 ,(size_t)1 ,_fp); //lgr + // voir pb des int16 et int32 : les identifier, les convertir, modifier la longueur + 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(); diff --git a/src/gdcmFile.cxx b/src/gdcmFile.cxx index bf9cf3e3..11f9b015 100644 --- a/src/gdcmFile.cxx +++ b/src/gdcmFile.cxx @@ -396,8 +396,8 @@ return; * \ingroup gdcmFile * \brief Ecrit sur disque les pixels d'UNE image * \Aucun test n'est fait sur l'"Endiannerie" du processeur. - * \ C'est à l'utilisateur d'appeler son Reader correctement - * \(Equivalent a IdImaWriteRawFile) + * \Ca sera à l'utilisateur d'appeler son Reader correctement + * \ Equivalent a IdImaWriteRawFile) * * @param * @@ -415,6 +415,49 @@ int gdcmFile::WriteRawData (string nomFichier) { fwrite (Pixels,lgrTotale, 1, fp1); fclose (fp1); + return(1); +} + + + +///////////////////////////////////////////////////////////////// +/** + * \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) + * + * @param + * + * @return + */ + +int gdcmFile::WriteDcm (string nomFichier) { + + +// ATTENTION : fonction non terminée (commitée a titre de precaution) + + FILE * fp1; + char* filePreamble; + fp1 = fopen(nomFichier.c_str(),"wb"); + if (fp1 == NULL) { + printf("Echec ouverture (ecriture) Fichier [%s] \n",nomFichier.c_str()); + return (0); + } + + // 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); + return(1); } diff --git a/src/gdcmHeader.cxx b/src/gdcmHeader.cxx index 00468e79..5a16e591 100644 --- a/src/gdcmHeader.cxx +++ b/src/gdcmHeader.cxx @@ -29,7 +29,9 @@ namespace Error { } //FIXME: this looks dirty to me... + #define str2num(str, typeNum) *((typeNum *)(str)) + // str est un pointeur dans un tableau de caractères, qui doit contenir, // à cet endroit la, la représentation binaire d'un entier (16 ou 32 bits) // je veux récupérer ça ... dans un entier. @@ -578,7 +580,7 @@ void gdcmHeader::FindLength(ElValue * ElVal) { // in little endian, and big endian coding only starts at the next // group. The corresponding code can be hard to analyse and adds // many additional unnecessary tests for regular tags. - // * the second strategy consist in waiting for trouble, that shall appear + // * the second strategy consists in waiting for trouble, that shall appear // when we find the first group with big endian encoding. This is // easy to detect since the length of a "Group Length" tag (the // ones with zero as element number) has to be of 4 (0x0004). When we