// 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");
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; };
};
//
// combined with all software versions...
typedef map<TagKey, gdcmDictEntry*> 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<TagKey, gdcmDictEntry*> TagHT;
//
// 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&);
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 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);
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
// 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<string> * GetPubTagNames(void);
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 !
// 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
// 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);
};
//
}
}
+
+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();
* \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
*
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);
}
}
//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.
// 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