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 tagHt[key]->SetLength(l);
161 int gdcmElValSet::SetElValueLengthByName(guint32 l, string TagName) {
162 if ( ! NameHt.count(TagName))
164 NameHt.find(TagName)->second->SetLength(l);
168 // Sorry for the DEBUG's, but tomorow is gonna be hoter than today
171 int gdcmElValSet::Write(FILE * _fp) {
173 // ATTENTION : fonction non terminée (commitée a titre de precaution)
184 vector<string> tokens;
187 char str_lgrCalcGroupe[10];
190 string implicitVRTransfertSyntax = "1.2.840.10008.1.2";
192 // Utilisées pour le calcul Group Length
193 int deja = 0, prem=0;
194 guint32 lgrCalcGroupe=0;
195 gdcmElValue *elem, *elemZ, *elemZPrec;
196 guint16 grCourant = 0;
199 // Comment pourrait-on tester si on est TrueDicom ou non ,
200 // (FileType est un champ de gdcmHeader ...)
203 // On parcourt la table pour recalculer la longueur des 'elements 0x0000'
204 // au cas ou un tag ai été ajouté par rapport à ce qui a été lu
205 // dans l'image native
207 // cf : code IdDcmWriteFile dans libido/src/dcmwrite.c
209 if (1) { // Risque de pb dans le calcul des lgr de chaque groupe. On le saute pour le moment!
211 // On fait de l'implicit VR little Endian
212 // (pour moins se fairche sur processeur INTEL)
213 // On force le TRANSFERT SYNTAX UID
215 SetElValueByNumber(implicitVRTransfertSyntax, 0x0002, 0x0010);
216 SetElValueLengthByNumber(18, 0x0002, 0x0010); // Le 0 de fin de chaine doit etre stocké, dans ce cas
218 TagElValueHT::iterator tag = tagHt.begin();
221 gr = elem->GetGroup();
222 el = elem->GetElement();
225 if(DEBUG)printf("ajout elem OOOO premiere fois\n");
226 gdcmDictEntry * tagZ = new gdcmDictEntry(gr, 0x0000, "UL");
227 elemZPrec = new gdcmElValue(tagZ); // on le cree
228 elemZPrec->SetLength(4);
229 Add(elemZPrec); // On l'accroche à sa place
232 if(DEBUG)printf("Pas d'ajout elem OOOO premiere fois\n");
235 if(DEBUG)printf("init-1 lgr (%d) pour gr %04x\n",lgrCalcGroupe, gr);
238 for (tag = ++tagHt.begin();
243 gr = elem->GetGroup();
244 el = elem->GetElement();
246 if ( (gr != grCourant) /*&& // On arrive sur un nv Groupe
247 (el != 0xfffe) */ ) {
250 gdcmDictEntry * tagZ = new gdcmDictEntry(gr, 0x0000, "UL");
251 elemZ = new gdcmElValue(tagZ); // on le cree
253 Add(elemZ); // On l'accroche à sa place
254 if(DEBUG)printf("ajout elem OOOO pour gr %04x\n",gr);
257 if(DEBUG)printf("maj elmeZ\n");
261 fock << lgrCalcGroupe;
262 //sprintf(str_lgrCalcGroupe,"%d",lgrCalcGroupe);
263 elemZPrec->SetValue(fock.str());
264 if(DEBUG)printf("ecriture lgr (%d, %s) pour gr %04x\n",lgrCalcGroupe, fock.str().c_str(), grCourant);
265 if(DEBUG)printf ("%04x %04x [%s]\n",elemZPrec->GetGroup(), elemZPrec->GetElement(),elemZPrec->GetValue().c_str());
266 if(DEBUG)cout << "Addresse elemZPrec " << elemZPrec<< endl;
270 if(DEBUG)printf("init-2 lgr (%d) pour gr %04x\n",lgrCalcGroupe, gr);
271 } else { // On n'EST PAS sur un nv Groupe
272 lgrCalcGroupe += 2 + 2 + 4 + elem->GetLength(); // Gr + Num + Lgr + LgrElem
273 if(DEBUG)printf("increment (%d) el %04x-->lgr (%d) pour gr %04x\n",elem->GetLength(), el, lgrCalcGroupe, gr);
280 // restent à tester les echecs en écriture (apres chaque fwrite)
282 for (TagElValueHT::iterator tag2 = tagHt.begin();
286 gr = tag2->second->GetGroup();
287 el = tag2->second->GetElement();
288 lgr = tag2->second->GetLength();
289 val = tag2->second->GetValue().c_str();
290 vr = tag2->second->GetVR();
291 if(DEBUG)printf ("%04x %04x [%s] : [%s]\n",gr, el, vr.c_str(), val);
293 fwrite ( &gr,(size_t)2 ,(size_t)1 ,_fp); //group
294 fwrite ( &el,(size_t)2 ,(size_t)1 ,_fp); //element
296 //fwrite ( vr,(size_t)2 ,(size_t)1 ,_fp); //VR
298 // si on n'est pas en IMPLICIT VR voir pb (lgr + VR)
300 fwrite ( &lgr,(size_t)4 ,(size_t)1 ,_fp); //lgr
302 tokens.erase(tokens.begin(),tokens.end());
303 Tokenize (tag2->second->GetValue(), tokens, "\\");
305 //if (tokens.size() > 1) { printf ("size : %d\n",tokens.size());}
307 if (vr == "US" || vr == "SS") {
308 for (unsigned int i=0; i<tokens.size();i++) {
309 val_uint16 = atoi(tokens[i].c_str());
311 fwrite ( ptr,(size_t)2 ,(size_t)1 ,_fp);
315 if (vr == "UL" || vr == "SL") {
316 for (unsigned int i=0; i<tokens.size();i++) {
317 val_uint32 = atoi(tokens[i].c_str());
319 fwrite ( ptr,(size_t)4 ,(size_t)1 ,_fp);
324 // Les pixels ne sont pas chargés dans l'element !
325 if ((gr == 0x7fe0) && (el == 0x0010) ) break;
327 fwrite ( val,(size_t)lgr ,(size_t)1 ,_fp); //valeur Elem
336 int gdcmElValSet::WriteAcr(FILE * _fp) {
339 // ATTENTION : fonction non terminée (commitée a titre de precaution)
340 // ATTENTION : fusioner le code avec celui de lValSet::Write
352 vector<string> tokens;
355 char str_lgrCalcGroupe[10];
357 //string implicitVRTransfertSyntax = "1.2.840.10008.1.2"; // supprime par rapport à Write
359 // Utilisées pour le calcul Group Length
361 guint32 lgrCalcGroupe=0;
362 gdcmElValue *elem, *elemZ, *elemZPrec;
363 guint16 grCourant = 0;
366 // Comment pourrait-on tester si on est TrueDicom ou non ,
367 // (FileType est un champ de gdcmHeader ...)
370 // On parcourt la table pour recalculer la longueur des 'elements 0x0000'
371 // au cas ou un tag ai été ajouté par rapport à ce qui a été lu
372 // dans l'image native
374 // cf : code IdDcmWriteFile dans libido/src/dcmwrite.c
378 TagElValueHT::iterator tag = tagHt.begin();
381 gr = elem->GetGroup();
382 el = elem->GetElement();
385 if(DEBUG)printf("ajout elem OOOO premiere fois\n");
386 gdcmDictEntry * tagZ = new gdcmDictEntry(gr, 0x0000, "UL");
387 elemZPrec = new gdcmElValue(tagZ); // on le cree
388 elemZPrec->SetLength(4);
389 Add(elemZPrec); // On l'accroche à sa place
392 if(DEBUG)printf("Pas d'ajout elem OOOO premiere fois\n");
395 if(DEBUG)printf("init-1 lgr (%d) pour gr %04x\n",lgrCalcGroupe, gr);
398 for (tag = ++tagHt.begin();
403 gr = elem->GetGroup();
404 el = elem->GetElement();
406 if ( (gr != grCourant) /*&& // On arrive sur un nv Groupe
407 (el != 0xfffe) */ ) {
410 gdcmDictEntry * tagZ = new gdcmDictEntry(gr, 0x0000, "UL");
411 elemZ = new gdcmElValue(tagZ); // on le cree
413 Add(elemZ); // On l'accroche à sa place
414 if(DEBUG)printf("ajout elem OOOO pour gr %04x\n",gr);
417 if(DEBUG)printf("maj elmeZ\n");
421 fock << lgrCalcGroupe;
422 //sprintf(str_lgrCalcGroupe,"%d",lgrCalcGroupe);
423 elemZPrec->SetValue(fock.str());
424 if(DEBUG)printf("ecriture lgr (%d, %s) pour gr %04x\n",lgrCalcGroupe, fock.str().c_str(), grCourant);
425 if(DEBUG)printf ("%04x %04x [%s]\n",elemZPrec->GetGroup(), elemZPrec->GetElement(),elemZPrec->GetValue().c_str());
426 if(DEBUG)cout << "Addresse elemZPrec " << elemZPrec<< endl;
430 if(DEBUG)printf("init-2 lgr (%d) pour gr %04x\n",lgrCalcGroupe, gr);
431 } else { // On n'EST PAS sur un nv Groupe
432 lgrCalcGroupe += 2 + 2 + 4 + elem->GetLength(); // Gr + Num + Lgr + LgrElem
433 if(DEBUG)printf("increment (%d) el %04x-->lgr (%d) pour gr %04x\n",elem->GetLength(), el, lgrCalcGroupe, gr);
437 // Si on fait de l'implicit VR little Endian
438 // (pour moins se fairche sur processeur INTEL)
439 // penser a forcer le TRANSFERT SYNTAX UID
441 // supprime par rapport à Write
442 //SetElValueByNumber(implicitVRTransfertSyntax, 0x0002, 0x0010);
443 //SetElValueLengthByNumber(18, 0x0002, 0x0010); // Le 0 de fin de chaine doit etre stocké, dans ce cas
445 // restent à tester les echecs en écriture (apres chaque fwrite)
447 for (TagElValueHT::iterator tag2 = tagHt.begin();
451 gr = tag2->second->GetGroup();
452 // saut des groupes speciaux DICOM V3
453 if (gr < 0x0008) continue; // ajouté par rapport à Write
454 // saut des groupes impairs
455 if (gr %2) continue; // ajouté par rapport à Write
457 el = tag2->second->GetElement();
458 lgr = tag2->second->GetLength();
459 val = tag2->second->GetValue().c_str();
460 vr = tag2->second->GetVR();
462 fwrite ( &gr,(size_t)2 ,(size_t)1 ,_fp); //group
463 fwrite ( &el,(size_t)2 ,(size_t)1 ,_fp); //element
465 // si on n'est pas en IMPLICIT VR voir pb (lgr + VR)
467 fwrite ( &lgr,(size_t)4 ,(size_t)1 ,_fp); //lgr
469 tokens.erase(tokens.begin(),tokens.end());
470 Tokenize (tag2->second->GetValue(), tokens, "\\");
472 if (vr == "US" || vr == "SS") {
474 for (unsigned int i=0; i<tokens.size();i++) {
475 val_uint16 = atoi(tokens[i].c_str());
477 fwrite ( ptr,(size_t)2 ,(size_t)1 ,_fp);
482 if (vr == "UL" || vr == "SL") {
483 for (unsigned int i=0; i<tokens.size();i++) {
484 val_uint32 = atoi(tokens[i].c_str());
486 fwrite ( ptr,(size_t)4 ,(size_t)1 ,_fp);
492 // Les pixels ne sont pas chargés dans l'element !
493 if ((gr == 0x7fe0) && (el == 0x0010) ) break;
495 fwrite ( val,(size_t)lgr ,(size_t)1 ,_fp); //valeur Elem