-// $Id: gdcmElValSet.cxx,v 1.21 2003/03/14 14:26:01 jpr Exp $
+// gdcmElValSet.cxx
+#include <sstream>
#include "gdcmUtil.h"
#include "gdcmElValSet.h"
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();
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;
}
}
"multiple entries for this key (FIXME) !");
return (0);
}
- // FIXME JPR: comments in English please !
- // m à j LgrElem
tagHt[key]->SetLength(l);
return(1);
}
return(1);
}
+// Sorry for the DEBUG's, but tomorow is gonna be hoter than today
+#define DEBUG 0
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;
//
// 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();
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
// 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 !
//
// 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!
+
+
+ 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);
}
}
size_t lgrTotale = nbFrames*nbLignes*nbCol*(nb/8);
return (lgrTotale);
-
}
-/////////////////////////////////////////////////////////////////
-/**
- * \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;
-
- int nb, nbu, highBit, signe;
- string str_nbFrames, str_nb, str_nbu, str_highBit, str_signe;
-
- unsigned short int mask = 0xffff;
-
- // 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);
-
- if (str_nbu == "gdcm::Unfound" ) {
- nbu = nb;
- } else {
- nbu = atoi(str_nbu.c_str() );
- }
-
- // Position du Bit de Poids Fort
- str_highBit=GetPubElValByNumber(0x0028,0x0102);
-
- if (str_highBit == "gdcm::Unfound" ) {
- highBit = nb - 1;
- } else {
- highBit = atoi(str_highBit.c_str() );
- }
-
- // Signe des Pixels 0 : Unsigned
- str_signe=GetPubElValByNumber(0x0028,0x0103);
-
- if (str_signe == "gdcm::Unfound" ) {
- signe = 1;
- } else {
- signe = atoi(str_signe.c_str() );
- }
-
- // Longueur en Octets des Pixels a lire
- size_t _lgrTotale = GetImageDataSize();
-
- //Pixels = (char *) g_malloc(_lgrTotale);
- _Pixels = (char *) malloc(_lgrTotale);
-
- GetPixels(lgrTotale, _Pixels);
-
- // On remet les Octets dans le bon ordre si besoin est
- if (nb != 8) {
- int _sw = GetSwapCode();
- _Swap (_Pixels, _sw, _lgrTotale, nb);
- }
-
- // On remet les Bits des Octets dans le bon ordre si besoin est
- //
- // ATTENTION : Jamais confronté a des pixels stockes sur 32 bits
- // avec moins de 32 bits utilises
- // et dont le bit de poids fort ne serait pas la ou on l'attend ...
- // --> ne marchera pas dans ce cas
- if (nbu!=nb){
- mask = mask >> (nb-nbu);
- int l=(int)_lgrTotale/(nb/8);
- unsigned short *deb = (unsigned short *)_Pixels;
- for(int i=0;i<l;i++) {
- *deb = (*deb >> (nbu-highBit-1)) & mask;
- deb ++;
- }
- }
- // On l'affecte à un champ du dcmFile
-
- Pixels = _Pixels;
- lgrTotale = _lgrTotale;
-
- // et on le retourne
- // ca fait double emploi, il faudra nettoyer ça
-
- 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
+ * \brief TODO
+ * \warning WARNING
*
- * @param rien
+ * @param
*
- * @return Pointeur sur la zone mémoire contenant les Pixels lus
+ * @return
*/
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);
+ _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);
int gdcmFile::GetImageDataIntoVector (void* destination, size_t MaxSize) {
// Question :
-// dans quel cas la Maxize sert-elle a quelque chose?
+// dans quel cas la MaxSize 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?
return;
}
+/////////////////////////////////////////////////////////////////
+/**
+ * \ingroup gdcmFile
+ * \brief TODO
+ * \warning WARNING doit-etre etre publique ?
+ *
+ * @param
+ *
+ * @return
+ */
+
+int gdcmFile::SetImageData(void * Data, size_t ExpectedSize) {
+
+ SetImageDataSize(ExpectedSize);
+
+ Pixels = Data;
+ lgrTotale = ExpectedSize;
+
+ return(1);
+}
+
+
+/////////////////////////////////////////////////////////////////
+/**
+ * \ingroup gdcmFile
+ * \brief TODO
+ * \
+ * \warning WARNING doit-etre etre publique ?
+ *
+ * @param
+ *
+ * @return
+ */
+
+void gdcmFile::SetImageDataSize(size_t ImageDataSize) {
+
+ string content1;
+ string content2;
+ char car[20];
+
+ sprintf(car,"%d",ImageDataSize);
+ content2=car;
+ SetPubElValByNumber(content2, 0x7fe0, 0x0010);
+
+ ImageDataSize+=8;
+ sprintf(car,"%d",ImageDataSize);
+ content1=car;
+ SetPubElValByNumber(content1, 0x7fe0, 0x0000);
+}
+
+
/////////////////////////////////////////////////////////////////
/**
* \ingroup gdcmFile