Je retourne à Cardio.
(pb des nouvelles images Philips à mettre dans un format traitable par FindTaggs)
See You
// which should be around 4500 entries which is the
// average dictionary size (said JPR)
//
- // En fait, je disais que dans LE Directory Dicom (dans son etat 2002)
- // il y a 1600 entrees.
+ // En fait, je disais que dans LE Directory Dicom (dans son etat 2001)
+ // il y a +/- 1600 entrees.
// Une valeur raisonable pour un majorant du nombre d'entrees
// dans une entete DICOM d'une image semble semble etre 300
// Si on 'decortique' les elements SQ (ce qui ne semble pas etre fait pour le moment)
TagElValueHT & GetTagHt(void);
int SetElValueByNumber(string content, guint32 group, guint32 element);
- int SetElValueByName(string content, string TagName);
+ int SetElValueByName (string content, string TagName);
+
+ int SetElValueLengthByNumber(guint32 l, guint32 group, guint32 element);
+ int SetElValueLengthByName (guint32 l, string TagName);
+
};
////////////////////////////////////////////////////////////////////////////
// Copies (at most MaxSize bytes) of data to caller's memory space.
// Returns an error code on failure (if MaxSize is not big enough)
- int PutImageDataHere(void* destination, size_t MaxSize );
+ int GetImageDataIntoVector(void* destination, size_t MaxSize );
// Question :
//
- // GetImageData et PutImageDataHere
+ // GetImageData et GetImageDataIntoVector
// Get et Put pour 2 fonctions qui font presque la meme chose :-(
//
// Ca sera à l'utilisateur d'appeler son Reader correctement
int WriteRawData (string nomFichier);
- int WriteDcm (string nomFichier);
+ int WriteDcm (string nomFichier);
};
//
return (0);
}
tagHt[key]->SetValue(content);
+
+ // Question : m à j LgrElem ?
+ tagHt[key]->SetLength(strlen(content.c_str()));
+
// FIXME should we really update the element length ?
tagHt[key]->SetLength(content.length());
+
return(1);
}
-
int ElValSet::SetElValueByName(string content, string TagName) {
if ( ! NameHt.count(TagName))
return 0;
if (NameHt.count(TagName) > 1) {
- dbg.Verbose(0, "ElValSet::SetElValue",
+ dbg.Verbose(0, "ElValSet::SetElValueByName",
"multipe entries for this key (FIXME) !");
return 0;
}
}
+int ElValSet::SetElValueLengthByNumber(guint32 l, guint32 group, guint32 element) {
+ TagKey key = gdcmDictEntry::TranslateToKey(group, element);
+ if ( ! tagHt.count(key))
+ return 0;
+ if (tagHt.count(key) > 1) {
+ dbg.Verbose(0, "ElValSet::SetElValueLengthByNumber",
+ "multiple entries for this key (FIXME) !");
+ return (0);
+ }
+ // m à j LgrElem
+ tagHt[key]->SetLength(l);
+ return(1);
+}
+
+
+int ElValSet::SetElValueLengthByName(guint32 l, string TagName) {
+ if ( ! NameHt.count(TagName))
+ return 0;
+ if (NameHt.count(TagName) > 1) {
+ dbg.Verbose(0, "ElValSet::SetElValueByName",
+ "multipe entries for this key (FIXME) !");
+ return 0;
+ }
+ NameHt.find(TagName)->second->SetLength(l);
+ return(1);
+}
+
int ElValSet::Write(FILE * _fp) {
guint32 val_int32;
guint16 val_int16;
void *ptr;
+ char str_lgrCalcGroupe[10];
string implicitVRTransfertSyntax = "1.2.840.10008.1.2";
-/* // Utilisées pour le calcul Group Length
+ // Utilisées pour le calcul Group Length
int deja = 0;
- guint32 lgrCalcGroupe;
- ElValue * elemZ, *elemZPrec;
+ guint32 lgrCalcGroupe=0;
+ ElValue *elem, *elemZ, *elemZPrec;
guint16 grCourant = 0;
-*/
-
// Question :
- // Comment pourrait-on tester si on est TRueDicom ou non ,
+ // Comment pourrait-on tester si on est TrueDicom ou non ,
// (FileType est un champ de gdcmHeader ...)
//
// au cas ou un tag ai été ajouté par rapport à ce qui a été lu
// dans l'image native
//
- // cf : code IdDcmWriteFile
-
-/*
- // Pas le temps de finir
- // voir libido/src/dcmwrite.c
- //
- // mais avant ... voir si le 'group length', lorsqu'il est present
- // sert encore a qq chose
- // patcher une image DICOM, mettre une lgr erronnée
- // et voir si e-film la reconnait ...
-
+ // cf : code IdDcmWriteFile dans libido/src/dcmwrite.c
for (TagElValueHT::iterator tag = tagHt.begin();
tag != tagHt.end();
++tag){
-
- elemZ = tag->second;
+
+ elem = tag->second;
+ printf("gr %04x el %04x lgr %d\n",elem->GetGroup(), elem->GetElement(), elem->GetLength());
- if ( (elemZ->GetGroup() != grCourant) &&
- (elemZ->GetGroup() != 0xfffe) ) { // On arrive sur un nv Groupe
+ if ( (elem->GetGroup() != grCourant) &&
+ (elem->GetGroup() != 0xfffe) ) { // On arrive sur un nv Groupe
- if(elemZ->GetNum != 0x0000) { // pas d'element 'Lgr groupe'
- // On le crée
- gdcmDictEntry * tagZ = IsInDicts(tag->second->GetGroup(), 0);
- elemZ = new (ElValue(tagZ)); // on le cree
- elemZ.SetLength(4);
+ 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");
+ elemZ = new ElValue(tagZ); // on le cree
+ elemZ->SetLength(4);
Add(elemZ); // On l'accroche à sa place
}
if (deja) {
-
- // A FINIR
+ sprintf(str_lgrCalcGroupe,"%d",lgrCalcGroupe);
+ elemZPrec->SetValue(str_lgrCalcGroupe);
+ lgrCalcGroupe = 0;
}
deja = 1;
+
+ lgrCalcGroupe = 12; //2 + 2 + 4 + 4; // Gr + Num + Lgr + LgrGroupe
+ printf ("lgrCalcGroupe %d\n",lgrCalcGroupe);
+
elemZPrec = elemZ;
- grCourant = elemZ->GetGroup();
- lgrCalcGroupe = 12; //2 + 2 + 4 + 4; // lgr (Gr + Num + LgrElem + LgrGroupe)
+ grCourant = elem->GetGroup();
} else { // On n'EST PAS sur un nv Groupe
- lgrCalcGroupe += 2 + 2; // lgr (Gr + Num )
-
- if (IsVrUnknowkn()) {
-
- // A FINIR
-
- }
+ printf ("lgrCalcGroupe avant : %d LgrElem %d\n",lgrCalcGroupe,elem->GetLength());
+
+ lgrCalcGroupe += 2 + 2 + 4 + elem->GetLength(); // Gr + Num + Lgr + LgrElem
- // A FINIR
- }
+ printf ("lgrCalcGroupe apres %d\n",lgrCalcGroupe);
-*/
+ }
+ }
- // Si on fait de l'implicit VR littele Endian
+ // Si on fait de l'implicit VR little Endian
// (pour moins se fairche sur processeur INTEL)
- // penser a forcer le SYNTAX TRANSFERT UID
+ // 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
// restent à tester les echecs en écriture (apres chaque fwrite)
#include "gdcm.h"
+
/**
* \ingroup gdcmElValue
* \brief Constructor from a given gdcmDictEntry
* @param in Pointer to existing dictionary entry
*/
+
ElValue::ElValue(gdcmDictEntry* in) {
ImplicitVr = false;
entry = in;
* @return Pointeur sur la zone mémoire contenant les Pixels lus
*/
+/*
void * gdcmFile::GetImageData (void) {
char* _Pixels;
return (_Pixels);
}
+*/
+
+/////////////////////////////////////////////////////////////////
+/**
+ * \ingroup gdcmFile
+ * \brief amene en mémoire les Pixels d'une image NON COMPRESSEE
+ * \Aucun test n'est fait pour le moment sur le caractere compresse ou non de l'image
+ *
+ * @param rien
+ *
+ * @return Pointeur sur la zone mémoire contenant les Pixels lus
+ */
+
+void * gdcmFile::GetImageData (void) {
+ char * _Pixels;
+ // Longueur en Octets des Pixels a lire
+ size_t taille = GetImageDataSize();// ne faudrait-il pas la stocker?
+ _Pixels = (char *) malloc(taille);
+ GetImageDataIntoVector(_Pixels, taille);
+
+ // On l'affecte à un champ du dcmFile
+ Pixels = _Pixels;
+ lgrTotale = taille;
+
+ // et on le retourne
+ // ca fait double emploi, il faudra nettoyer ça
+
+ return(_Pixels);
+}
+
+
/////////////////////////////////////////////////////////////////
/**
* @return
*/
-int gdcmFile::PutImageDataHere (void* destination, size_t MaxSize) {
+int gdcmFile::GetImageDataIntoVector (void* destination, size_t MaxSize) {
// Question :
// dans quel cas la Maxize sert-elle a quelque chose?
// Longueur en Octets des Pixels a lire
size_t _lgrTotale = GetImageDataSize(); // ne faudrait-il pas la stocker?
- // si lgrTotale < MaxSize ==> Gros pb . A VOIR
+ // si lgrTotale < MaxSize ==> Gros pb
+ // -> on résoud à la goret
- lgrTotale = MaxSize; // pour garder le code identique avec GetImageData
- //Pixels = (char *) malloc(lgrTotale); // pour garder le code identique avec GetImageData
+ if ( _lgrTotale < MaxSize ) MaxSize = _lgrTotale;
- GetPixels(lgrTotale, Pixels);
-
-
+ GetPixels(MaxSize, destination);
+
// Nombre de Bits Alloues pour le stockage d'un Pixel
str_nb=gdcmHeader::GetPubElValByNumber(0x0028,0x0100);
signe = atoi(str_signe.c_str() );
}
-
// On remet les Octets dans le bon ordre si besoin est
if (nb != 8) {
int _sw = GetSwapCode();
- _Swap (Pixels, _sw, lgrTotale, nb);
+ _Swap (destination, _sw, _lgrTotale, nb);
}
// On remet les Bits des Octets dans le bon ordre si besoin est
// --> ne marchera pas dans ce cas
if (nbu!=nb){
mask = mask >> (nb-nbu);
- int l=(int)lgrTotale/(nb/8);
+ int l=(int)MaxSize/(nb/8);
unsigned short *deb = (unsigned short *)Pixels;
for(int i=0;i<l;i++) {
*deb = (*deb >> (nbu-highBit-1)) & mask;
// VOIR s'il ne faudrait pas l'affecter à un champ du dcmHeader
- //return (Pixels); // pour garder le code identique avec GetImageData
return 1;
}
+
//
// Je laisse le code integral, au cas ça puisse etre reutilise ailleurs
//
* \brief Ecrit sur disque les pixels d'UNE image
* \Aucun test n'est fait sur l'"Endiannerie" du processeur.
* \Ca sera à l'utilisateur d'appeler son Reader correctement
- * \ Equivalent a IdImaWriteRawFile)
+ * \ (Equivalent a IdImaWriteRawFile)
*
* @param
*
* \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.
+ * \Ca fonctionnera correctement (?) sur processeur Intel
* \ (Equivalent a IdDcmWrite)
*
* @param
int gdcmFile::WriteDcm (string nomFichier) {
-
// ATTENTION : fonction non terminée (commitée a titre de precaution)
FILE * fp1;