5 #include "gdcmElValSet.h"
8 TagElValueHT & gdcmElValSet::GetTagHt(void) {
12 void gdcmElValSet::Add(gdcmElValue * newElValue) {
13 tagHt [newElValue->GetKey()] = newElValue;
14 NameHt[newElValue->GetName()] = newElValue;
17 // TODO : faire un gdcmElValSet::ReplaceOrCreate qui remplace si ça existe, qui cree sinon
19 void gdcmElValSet::ReplaceOrCreate(gdcmElValue * newElValue) {
21 TagKey key = newElValue->GetKey();
23 if (tagHt.count(key) > 1)
24 dbg.Verbose(0, "gdcmElValSet::GetElValueByNumber",
25 "multiple entries for this key (FIXME) !");
27 if (tagHt.count(key)) {
29 tagHt.erase(newElValue->GetName());
32 tagHt [key] = newElValue;
33 NameHt[newElValue->GetName()] = newElValue;
37 void gdcmElValSet::Print(ostream & os) {
38 for (TagElValueHT::iterator tag = tagHt.begin();
41 os << tag->first << ": ";
42 os << "[" << tag->second->GetValue() << "]";
43 os << "[" << tag->second->GetName() << "]";
44 os << "[" << tag->second->GetVR() << "]";
45 os << " lgr : " << tag->second->GetLength();
50 void gdcmElValSet::PrintByName(ostream & os) {
51 for (TagElValueNameHT::iterator tag = NameHt.begin();
54 os << tag->first << ": ";
55 os << "[" << tag->second->GetValue() << "]";
56 os << "[" << tag->second->GetKey() << "]";
57 os << "[" << tag->second->GetVR() << "]" << endl;
61 gdcmElValue* gdcmElValSet::GetElementByNumber(guint32 group, guint32 element) {
62 TagKey key = gdcmDictEntry::TranslateToKey(group, element);
63 if ( ! tagHt.count(key))
64 return (gdcmElValue*)0;
65 if (tagHt.count(key) > 1)
66 dbg.Verbose(0, "gdcmElValSet::GetElementByNumber",
67 "multiple entries for this key (FIXME) !");
68 return tagHt.find(key)->second;
71 gdcmElValue* gdcmElValSet::GetElementByName(string TagName) {
72 if ( ! NameHt.count(TagName))
73 return (gdcmElValue*)0;
74 if (NameHt.count(TagName) > 1)
75 dbg.Verbose(0, "gdcmElValSet::GetElement",
76 "multipe entries for this key (FIXME) !");
77 return NameHt.find(TagName)->second;
80 string gdcmElValSet::GetElValueByNumber(guint32 group, guint32 element) {
81 TagKey key = gdcmDictEntry::TranslateToKey(group, element);
82 if ( ! tagHt.count(key))
83 return "gdcm::Unfound";
84 if (tagHt.count(key) > 1)
85 dbg.Verbose(0, "gdcmElValSet::GetElValueByNumber",
86 "multiple entries for this key (FIXME) !");
87 return tagHt.find(key)->second->GetValue();
90 string gdcmElValSet::GetElValueByName(string TagName) {
91 if ( ! NameHt.count(TagName))
92 return "gdcm::Unfound";
93 if (NameHt.count(TagName) > 1)
94 dbg.Verbose(0, "gdcmElValSet::GetElValue",
95 "multipe entries for this key (FIXME) !");
96 return NameHt.find(TagName)->second->GetValue();
99 int gdcmElValSet::SetElValueByNumber(string content,
100 guint32 group, guint32 element) {
101 TagKey key = gdcmDictEntry::TranslateToKey(group, element);
102 if ( ! tagHt.count(key))
104 if (tagHt.count(key) > 1) {
105 dbg.Verbose(0, "gdcmElValSet::SetElValueByNumber",
106 "multiple entries for this key (FIXME) !");
109 tagHt[key]->SetValue(content);
111 // Question : m à j LgrElem ?
112 tagHt[key]->SetLength(strlen(content.c_str()));
114 // FIXME should we really update the element length ?
115 tagHt[key]->SetLength(content.length());
120 int gdcmElValSet::SetElValueByName(string content, string TagName) {
121 if ( ! NameHt.count(TagName))
123 if (NameHt.count(TagName) > 1) {
124 dbg.Verbose(0, "gdcmElValSet::SetElValueByName",
125 "multipe entries for this key (FIXME) !");
128 NameHt.find(TagName)->second->SetValue(content);
129 NameHt.find(TagName)->second->SetLength(strlen(content.c_str()));
134 * \ingroup gdcmElValSet
135 * \brief Generate a free TagKey i.e. a TagKey that is not present
136 * in the TagHt dictionary. One of the potential usage is
137 * to add gdcm generated additional informartion to the ElValSet
138 * (see gdcmHeader::AddAndDefaultElements).
139 * @param group The generated tag must belong to this group.
140 * @return The element of tag with given group which is fee.
142 guint32 gdcmElValSet::GenerateFreeTagKeyInGroup(guint32 group) {
143 for (guint32 elem = 0; elem < UINT32_MAX; elem++) {
144 TagKey key = gdcmDictEntry::TranslateToKey(group, elem);
145 if (tagHt.count(key) == 0)
151 int gdcmElValSet::SetElValueLengthByNumber(guint32 l,
152 guint32 group, guint32 element) {
153 TagKey key = gdcmDictEntry::TranslateToKey(group, element);
154 if ( ! tagHt.count(key))
156 if (tagHt.count(key) > 1) {
157 dbg.Verbose(0, "gdcmElValSet::SetElValueLengthByNumber",
158 "multiple entries for this key (FIXME) !");
161 tagHt[key]->SetLength(l);
166 int gdcmElValSet::SetElValueLengthByName(guint32 l, string TagName) {
167 if ( ! NameHt.count(TagName))
169 if (NameHt.count(TagName) > 1) {
170 dbg.Verbose(0, "gdcmElValSet::SetElValueByName",
171 "multipe entries for this key (FIXME) !");
174 NameHt.find(TagName)->second->SetLength(l);
178 // Sorry for the DEBUG's, but tomorow is gonna be hoter than today
181 int gdcmElValSet::Write(FILE * _fp) {
183 // ATTENTION : fonction non terminée (commitée a titre de precaution)
194 vector<string> tokens;
197 char str_lgrCalcGroupe[10];
200 string implicitVRTransfertSyntax = "1.2.840.10008.1.2";
202 // Utilisées pour le calcul Group Length
203 int deja = 0, prem=0;
204 guint32 lgrCalcGroupe=0;
205 gdcmElValue *elem, *elemZ, *elemZPrec;
206 guint16 grCourant = 0;
209 // Comment pourrait-on tester si on est TrueDicom ou non ,
210 // (FileType est un champ de gdcmHeader ...)
213 // On parcourt la table pour recalculer la longueur des 'elements 0x0000'
214 // au cas ou un tag ai été ajouté par rapport à ce qui a été lu
215 // dans l'image native
217 // cf : code IdDcmWriteFile dans libido/src/dcmwrite.c
219 if (1) { // Risque de pb dans le calcul des lgr de chaque groupe. On le saute pour le moment!
221 // On fait de l'implicit VR little Endian
222 // (pour moins se fairche sur processeur INTEL)
223 // On force le TRANSFERT SYNTAX UID
225 SetElValueByNumber(implicitVRTransfertSyntax, 0x0002, 0x0010);
226 SetElValueLengthByNumber(18, 0x0002, 0x0010); // Le 0 de fin de chaine doit etre stocké, dans ce cas
228 TagElValueHT::iterator tag = tagHt.begin();
231 gr = elem->GetGroup();
232 el = elem->GetElement();
235 if(DEBUG)printf("ajout elem OOOO premiere fois\n");
236 gdcmDictEntry * tagZ = new gdcmDictEntry(gr, 0x0000, "UL");
237 elemZPrec = new gdcmElValue(tagZ); // on le cree
238 elemZPrec->SetLength(4);
239 Add(elemZPrec); // On l'accroche à sa place
242 if(DEBUG)printf("Pas d'ajout elem OOOO premiere fois\n");
245 if(DEBUG)printf("init-1 lgr (%d) pour gr %04x\n",lgrCalcGroupe, gr);
248 for (tag = ++tagHt.begin();
253 gr = elem->GetGroup();
254 el = elem->GetElement();
256 if ( (gr != grCourant) /*&& // On arrive sur un nv Groupe
257 (el != 0xfffe) */ ) {
260 gdcmDictEntry * tagZ = new gdcmDictEntry(gr, 0x0000, "UL");
261 elemZ = new gdcmElValue(tagZ); // on le cree
263 Add(elemZ); // On l'accroche à sa place
264 if(DEBUG)printf("ajout elem OOOO pour gr %04x\n",gr);
267 if(DEBUG)printf("maj elmeZ\n");
271 fock << lgrCalcGroupe;
272 //sprintf(str_lgrCalcGroupe,"%d",lgrCalcGroupe);
273 elemZPrec->SetValue(fock.str());
274 if(DEBUG)printf("ecriture lgr (%d, %s) pour gr %04x\n",lgrCalcGroupe, fock.str().c_str(), grCourant);
275 if(DEBUG)printf ("%04x %04x [%s]\n",elemZPrec->GetGroup(), elemZPrec->GetElement(),elemZPrec->GetValue().c_str());
276 if(DEBUG)cout << "Addresse elemZPrec " << elemZPrec<< endl;
280 if(DEBUG)printf("init-2 lgr (%d) pour gr %04x\n",lgrCalcGroupe, gr);
281 } else { // On n'EST PAS sur un nv Groupe
282 lgrCalcGroupe += 2 + 2 + 4 + elem->GetLength(); // Gr + Num + Lgr + LgrElem
283 if(DEBUG)printf("increment (%d) el %04x-->lgr (%d) pour gr %04x\n",elem->GetLength(), el, lgrCalcGroupe, gr);
290 // restent à tester les echecs en écriture (apres chaque fwrite)
292 for (TagElValueHT::iterator tag2 = tagHt.begin();
296 gr = tag2->second->GetGroup();
297 el = tag2->second->GetElement();
298 lgr = tag2->second->GetLength();
299 val = tag2->second->GetValue().c_str();
300 vr = tag2->second->GetVR();
301 if(DEBUG)printf ("%04x %04x [%s] : [%s]\n",gr, el, vr.c_str(), val);
303 fwrite ( &gr,(size_t)2 ,(size_t)1 ,_fp); //group
304 fwrite ( &el,(size_t)2 ,(size_t)1 ,_fp); //element
306 //fwrite ( vr,(size_t)2 ,(size_t)1 ,_fp); //VR
308 // si on n'est pas en IMPLICIT VR voir pb (lgr + VR)
310 fwrite ( &lgr,(size_t)4 ,(size_t)1 ,_fp); //lgr
312 tokens.erase(tokens.begin(),tokens.end());
313 Tokenize (tag2->second->GetValue(), tokens, "\\");
315 //if (tokens.size() > 1) { printf ("size : %d\n",tokens.size());}
317 if (vr == "US" || vr == "SS") {
318 for (unsigned int i=0; i<tokens.size();i++) {
319 val_uint16 = atoi(tokens[i].c_str());
321 fwrite ( ptr,(size_t)2 ,(size_t)1 ,_fp);
325 if (vr == "UL" || vr == "SL") {
326 for (unsigned int i=0; i<tokens.size();i++) {
327 val_uint32 = atoi(tokens[i].c_str());
329 fwrite ( ptr,(size_t)4 ,(size_t)1 ,_fp);
334 // Les pixels ne sont pas chargés dans l'element !
335 if ((gr == 0x7fe0) && (el == 0x0010) ) break;
337 fwrite ( val,(size_t)lgr ,(size_t)1 ,_fp); //valeur Elem
346 int gdcmElValSet::WriteAcr(FILE * _fp) {
349 // ATTENTION : fonction non terminée (commitée a titre de precaution)
350 // ATTENTION : fusioner le code avec celui de lValSet::Write
362 vector<string> tokens;
365 char str_lgrCalcGroupe[10];
367 //string implicitVRTransfertSyntax = "1.2.840.10008.1.2"; // supprime par rapport à Write
369 // Utilisées pour le calcul Group Length
371 guint32 lgrCalcGroupe=0;
372 gdcmElValue *elem, *elemZ, *elemZPrec;
373 guint16 grCourant = 0;
376 // Comment pourrait-on tester si on est TrueDicom ou non ,
377 // (FileType est un champ de gdcmHeader ...)
380 // On parcourt la table pour recalculer la longueur des 'elements 0x0000'
381 // au cas ou un tag ai été ajouté par rapport à ce qui a été lu
382 // dans l'image native
384 // cf : code IdDcmWriteFile dans libido/src/dcmwrite.c
388 TagElValueHT::iterator tag = tagHt.begin();
391 gr = elem->GetGroup();
392 el = elem->GetElement();
395 if(DEBUG)printf("ajout elem OOOO premiere fois\n");
396 gdcmDictEntry * tagZ = new gdcmDictEntry(gr, 0x0000, "UL");
397 elemZPrec = new gdcmElValue(tagZ); // on le cree
398 elemZPrec->SetLength(4);
399 Add(elemZPrec); // On l'accroche à sa place
402 if(DEBUG)printf("Pas d'ajout elem OOOO premiere fois\n");
405 if(DEBUG)printf("init-1 lgr (%d) pour gr %04x\n",lgrCalcGroupe, gr);
408 for (tag = ++tagHt.begin();
413 gr = elem->GetGroup();
414 el = elem->GetElement();
416 if ( (gr != grCourant) /*&& // On arrive sur un nv Groupe
417 (el != 0xfffe) */ ) {
420 gdcmDictEntry * tagZ = new gdcmDictEntry(gr, 0x0000, "UL");
421 elemZ = new gdcmElValue(tagZ); // on le cree
423 Add(elemZ); // On l'accroche à sa place
424 if(DEBUG)printf("ajout elem OOOO pour gr %04x\n",gr);
427 if(DEBUG)printf("maj elmeZ\n");
431 fock << lgrCalcGroupe;
432 //sprintf(str_lgrCalcGroupe,"%d",lgrCalcGroupe);
433 elemZPrec->SetValue(fock.str());
434 if(DEBUG)printf("ecriture lgr (%d, %s) pour gr %04x\n",lgrCalcGroupe, fock.str().c_str(), grCourant);
435 if(DEBUG)printf ("%04x %04x [%s]\n",elemZPrec->GetGroup(), elemZPrec->GetElement(),elemZPrec->GetValue().c_str());
436 if(DEBUG)cout << "Addresse elemZPrec " << elemZPrec<< endl;
440 if(DEBUG)printf("init-2 lgr (%d) pour gr %04x\n",lgrCalcGroupe, gr);
441 } else { // On n'EST PAS sur un nv Groupe
442 lgrCalcGroupe += 2 + 2 + 4 + elem->GetLength(); // Gr + Num + Lgr + LgrElem
443 if(DEBUG)printf("increment (%d) el %04x-->lgr (%d) pour gr %04x\n",elem->GetLength(), el, lgrCalcGroupe, gr);
447 // Si on fait de l'implicit VR little Endian
448 // (pour moins se fairche sur processeur INTEL)
449 // penser a forcer le TRANSFERT SYNTAX UID
451 // supprime par rapport à Write
452 //SetElValueByNumber(implicitVRTransfertSyntax, 0x0002, 0x0010);
453 //SetElValueLengthByNumber(18, 0x0002, 0x0010); // Le 0 de fin de chaine doit etre stocké, dans ce cas
455 // restent à tester les echecs en écriture (apres chaque fwrite)
457 for (TagElValueHT::iterator tag2 = tagHt.begin();
461 gr = tag2->second->GetGroup();
462 // saut des groupes speciaux DICOM V3
463 if (gr < 0x0008) continue; // ajouté par rapport à Write
464 // saut des groupes impairs
465 if (gr %2) continue; // ajouté par rapport à Write
467 el = tag2->second->GetElement();
468 lgr = tag2->second->GetLength();
469 val = tag2->second->GetValue().c_str();
470 vr = tag2->second->GetVR();
472 fwrite ( &gr,(size_t)2 ,(size_t)1 ,_fp); //group
473 fwrite ( &el,(size_t)2 ,(size_t)1 ,_fp); //element
475 // si on n'est pas en IMPLICIT VR voir pb (lgr + VR)
477 fwrite ( &lgr,(size_t)4 ,(size_t)1 ,_fp); //lgr
479 tokens.erase(tokens.begin(),tokens.end());
480 Tokenize (tag2->second->GetValue(), tokens, "\\");
482 if (vr == "US" || vr == "SS") {
484 for (unsigned int i=0; i<tokens.size();i++) {
485 val_uint16 = atoi(tokens[i].c_str());
487 fwrite ( ptr,(size_t)2 ,(size_t)1 ,_fp);
492 if (vr == "UL" || vr == "SL") {
493 for (unsigned int i=0; i<tokens.size();i++) {
494 val_uint32 = atoi(tokens[i].c_str());
496 fwrite ( ptr,(size_t)4 ,(size_t)1 ,_fp);
502 // Les pixels ne sont pas chargés dans l'element !
503 if ((gr == 0x7fe0) && (el == 0x0010) ) break;
505 fwrite ( val,(size_t)lgr ,(size_t)1 ,_fp); //valeur Elem