5 #include "gdcmElValSet.h"
8 TagElValueHT & gdcmElValSet::GetTagHt(void) {
12 void gdcmElValSet::Add(gdcmElValue * newElValue) {
13 cout << "#### gdcmElValSet::Add" << newElValue->GetKey() << newElValue->GetName() << endl;
14 tagHt [newElValue->GetKey()] = newElValue;
15 NameHt[newElValue->GetName()] = newElValue;
18 // TODO : faire un gdcmElValSet::ReplaceOrCreate qui remplace si ça existe, qui cree sinon
20 void gdcmElValSet::ReplaceOrCreate(gdcmElValue * newElValue) {
22 TagKey key = newElValue->GetKey();
24 if (tagHt.count(key) > 1)
25 dbg.Verbose(0, "gdcmElValSet::GetElValueByNumber",
26 "multiple entries for this key (FIXME) !");
28 if (tagHt.count(key)) {
30 tagHt.erase(newElValue->GetName());
33 tagHt [key] = newElValue;
34 NameHt[newElValue->GetName()] = newElValue;
38 void gdcmElValSet::Print(ostream & os) {
39 for (TagElValueHT::iterator tag = tagHt.begin();
42 os << tag->first << ": ";
43 os << "[" << tag->second->GetValue() << "]";
44 os << "[" << tag->second->GetName() << "]";
45 os << "[" << tag->second->GetVR() << "]";
46 os << " lgr : " << tag->second->GetLength();
51 void gdcmElValSet::PrintByName(ostream & os) {
52 for (TagElValueNameHT::iterator tag = NameHt.begin();
55 os << tag->first << ": ";
56 os << "[" << tag->second->GetValue() << "]";
57 os << "[" << tag->second->GetKey() << "]";
58 os << "[" << tag->second->GetVR() << "]" << endl;
62 gdcmElValue* gdcmElValSet::GetElementByNumber(guint32 group, guint32 element) {
63 TagKey key = gdcmDictEntry::TranslateToKey(group, element);
64 if ( ! tagHt.count(key))
65 return (gdcmElValue*)0;
66 if (tagHt.count(key) > 1)
67 dbg.Verbose(0, "gdcmElValSet::GetElementByNumber",
68 "multiple entries for this key (FIXME) !");
69 return tagHt.find(key)->second;
72 gdcmElValue* gdcmElValSet::GetElementByName(string TagName) {
73 if ( ! NameHt.count(TagName))
74 return (gdcmElValue*)0;
75 if (NameHt.count(TagName) > 1)
76 dbg.Verbose(0, "gdcmElValSet::GetElement",
77 "multipe entries for this key (FIXME) !");
78 return NameHt.find(TagName)->second;
81 string gdcmElValSet::GetElValueByNumber(guint32 group, guint32 element) {
82 TagKey key = gdcmDictEntry::TranslateToKey(group, element);
83 if ( ! tagHt.count(key))
84 return "gdcm::Unfound";
85 if (tagHt.count(key) > 1)
86 dbg.Verbose(0, "gdcmElValSet::GetElValueByNumber",
87 "multiple entries for this key (FIXME) !");
88 return tagHt.find(key)->second->GetValue();
91 string gdcmElValSet::GetElValueByName(string TagName) {
92 if ( ! NameHt.count(TagName))
93 return "gdcm::Unfound";
94 if (NameHt.count(TagName) > 1)
95 dbg.Verbose(0, "gdcmElValSet::GetElValue",
96 "multipe entries for this key (FIXME) !");
97 return NameHt.find(TagName)->second->GetValue();
100 int gdcmElValSet::SetElValueByNumber(string content,
101 guint32 group, guint32 element) {
102 TagKey key = gdcmDictEntry::TranslateToKey(group, element);
103 if ( ! tagHt.count(key))
105 if (tagHt.count(key) > 1) {
106 dbg.Verbose(0, "gdcmElValSet::SetElValueByNumber",
107 "multiple entries for this key (FIXME) !");
110 tagHt[key]->SetValue(content);
112 // Question : m à j LgrElem ?
113 tagHt[key]->SetLength(strlen(content.c_str()));
115 // FIXME should we really update the element length ?
116 tagHt[key]->SetLength(content.length());
121 int gdcmElValSet::SetElValueByName(string content, string TagName) {
122 if ( ! NameHt.count(TagName))
124 if (NameHt.count(TagName) > 1) {
125 dbg.Verbose(0, "gdcmElValSet::SetElValueByName",
126 "multipe entries for this key (FIXME) !");
129 NameHt.find(TagName)->second->SetValue(content);
130 NameHt.find(TagName)->second->SetLength(strlen(content.c_str()));
135 * \ingroup gdcmElValSet
136 * \brief Generate a free TagKey i.e. a TagKey that is not present
137 * in the TagHt dictionary. One of the potential usage is
138 * to add gdcm generated additional informartion to the ElValSet
139 * (see gdcmHeader::AddAndDefaultElements).
140 * @param group The generated tag must belong to this group.
141 * @return The element of tag with given group which is fee.
143 guint32 gdcmElValSet::GenerateFreeTagKeyInGroup(guint32 group) {
144 for (guint32 elem = 0; elem < UINT32_MAX; elem++) {
145 TagKey key = gdcmDictEntry::TranslateToKey(group, elem);
146 if (tagHt.count(key) == 0)
152 int gdcmElValSet::SetElValueLengthByNumber(guint32 l,
153 guint32 group, guint32 element) {
154 TagKey key = gdcmDictEntry::TranslateToKey(group, element);
155 if ( ! tagHt.count(key))
157 if (tagHt.count(key) > 1) {
158 dbg.Verbose(0, "gdcmElValSet::SetElValueLengthByNumber",
159 "multiple entries for this key (FIXME) !");
162 tagHt[key]->SetLength(l);
167 int gdcmElValSet::SetElValueLengthByName(guint32 l, string TagName) {
168 if ( ! NameHt.count(TagName))
170 if (NameHt.count(TagName) > 1) {
171 dbg.Verbose(0, "gdcmElValSet::SetElValueByName",
172 "multipe entries for this key (FIXME) !");
175 NameHt.find(TagName)->second->SetLength(l);
179 // Sorry for the DEBUG's, but tomorow is gonna be hoter than today
182 int gdcmElValSet::Write(FILE * _fp) {
184 // ATTENTION : fonction non terminée (commitée a titre de precaution)
195 vector<string> tokens;
198 char str_lgrCalcGroupe[10];
201 string implicitVRTransfertSyntax = "1.2.840.10008.1.2";
203 // Utilisées pour le calcul Group Length
204 int deja = 0, prem=0;
205 guint32 lgrCalcGroupe=0;
206 gdcmElValue *elem, *elemZ, *elemZPrec;
207 guint16 grCourant = 0;
210 // Comment pourrait-on tester si on est TrueDicom ou non ,
211 // (FileType est un champ de gdcmHeader ...)
214 // On parcourt la table pour recalculer la longueur des 'elements 0x0000'
215 // au cas ou un tag ai été ajouté par rapport à ce qui a été lu
216 // dans l'image native
218 // cf : code IdDcmWriteFile dans libido/src/dcmwrite.c
220 if (1) { // Risque de pb dans le calcul des lgr de chaque groupe. On le saute pour le moment!
222 // On fait de l'implicit VR little Endian
223 // (pour moins se fairche sur processeur INTEL)
224 // On force le TRANSFERT SYNTAX UID
226 SetElValueByNumber(implicitVRTransfertSyntax, 0x0002, 0x0010);
227 SetElValueLengthByNumber(18, 0x0002, 0x0010); // Le 0 de fin de chaine doit etre stocké, dans ce cas
229 TagElValueHT::iterator tag = tagHt.begin();
232 gr = elem->GetGroup();
233 el = elem->GetElement();
236 if(DEBUG)printf("ajout elem OOOO premiere fois\n");
237 gdcmDictEntry * tagZ = new gdcmDictEntry(gr, 0x0000, "UL");
238 elemZPrec = new gdcmElValue(tagZ); // on le cree
239 elemZPrec->SetLength(4);
240 Add(elemZPrec); // On l'accroche à sa place
243 if(DEBUG)printf("Pas d'ajout elem OOOO premiere fois\n");
246 if(DEBUG)printf("init-1 lgr (%d) pour gr %04x\n",lgrCalcGroupe, gr);
249 for (tag = ++tagHt.begin();
254 gr = elem->GetGroup();
255 el = elem->GetElement();
257 if ( (gr != grCourant) /*&& // On arrive sur un nv Groupe
258 (el != 0xfffe) */ ) {
261 gdcmDictEntry * tagZ = new gdcmDictEntry(gr, 0x0000, "UL");
262 elemZ = new gdcmElValue(tagZ); // on le cree
264 Add(elemZ); // On l'accroche à sa place
265 if(DEBUG)printf("ajout elem OOOO pour gr %04x\n",gr);
268 if(DEBUG)printf("maj elmeZ\n");
272 fock << lgrCalcGroupe;
273 //sprintf(str_lgrCalcGroupe,"%d",lgrCalcGroupe);
274 elemZPrec->SetValue(fock.str());
275 if(DEBUG)printf("ecriture lgr (%d, %s) pour gr %04x\n",lgrCalcGroupe, fock.str().c_str(), grCourant);
276 if(DEBUG)printf ("%04x %04x [%s]\n",elemZPrec->GetGroup(), elemZPrec->GetElement(),elemZPrec->GetValue().c_str());
277 if(DEBUG)cout << "Addresse elemZPrec " << elemZPrec<< endl;
281 if(DEBUG)printf("init-2 lgr (%d) pour gr %04x\n",lgrCalcGroupe, gr);
282 } else { // On n'EST PAS sur un nv Groupe
283 lgrCalcGroupe += 2 + 2 + 4 + elem->GetLength(); // Gr + Num + Lgr + LgrElem
284 if(DEBUG)printf("increment (%d) el %04x-->lgr (%d) pour gr %04x\n",elem->GetLength(), el, lgrCalcGroupe, gr);
291 // restent à tester les echecs en écriture (apres chaque fwrite)
293 for (TagElValueHT::iterator tag2 = tagHt.begin();
297 gr = tag2->second->GetGroup();
298 el = tag2->second->GetElement();
299 lgr = tag2->second->GetLength();
300 val = tag2->second->GetValue().c_str();
301 vr = tag2->second->GetVR();
302 if(DEBUG)printf ("%04x %04x [%s] : [%s]\n",gr, el, vr.c_str(), val);
304 fwrite ( &gr,(size_t)2 ,(size_t)1 ,_fp); //group
305 fwrite ( &el,(size_t)2 ,(size_t)1 ,_fp); //element
307 //fwrite ( vr,(size_t)2 ,(size_t)1 ,_fp); //VR
309 // si on n'est pas en IMPLICIT VR voir pb (lgr + VR)
311 fwrite ( &lgr,(size_t)4 ,(size_t)1 ,_fp); //lgr
313 tokens.erase(tokens.begin(),tokens.end());
314 Tokenize (tag2->second->GetValue(), tokens, "\\");
316 //if (tokens.size() > 1) { printf ("size : %d\n",tokens.size());}
318 if (vr == "US" || vr == "SS") {
319 for (unsigned int i=0; i<tokens.size();i++) {
320 val_uint16 = atoi(tokens[i].c_str());
322 fwrite ( ptr,(size_t)2 ,(size_t)1 ,_fp);
326 if (vr == "UL" || vr == "SL") {
327 for (unsigned int i=0; i<tokens.size();i++) {
328 val_uint32 = atoi(tokens[i].c_str());
330 fwrite ( ptr,(size_t)4 ,(size_t)1 ,_fp);
335 // Les pixels ne sont pas chargés dans l'element !
336 if ((gr == 0x7fe0) && (el == 0x0010) ) break;
338 fwrite ( val,(size_t)lgr ,(size_t)1 ,_fp); //valeur Elem
347 int gdcmElValSet::WriteAcr(FILE * _fp) {
350 // ATTENTION : fonction non terminée (commitée a titre de precaution)
351 // ATTENTION : fusioner le code avec celui de lValSet::Write
363 vector<string> tokens;
366 char str_lgrCalcGroupe[10];
368 //string implicitVRTransfertSyntax = "1.2.840.10008.1.2"; // supprime par rapport à Write
370 // Utilisées pour le calcul Group Length
372 guint32 lgrCalcGroupe=0;
373 gdcmElValue *elem, *elemZ, *elemZPrec;
374 guint16 grCourant = 0;
377 // Comment pourrait-on tester si on est TrueDicom ou non ,
378 // (FileType est un champ de gdcmHeader ...)
381 // On parcourt la table pour recalculer la longueur des 'elements 0x0000'
382 // au cas ou un tag ai été ajouté par rapport à ce qui a été lu
383 // dans l'image native
385 // cf : code IdDcmWriteFile dans libido/src/dcmwrite.c
389 TagElValueHT::iterator tag = tagHt.begin();
392 gr = elem->GetGroup();
393 el = elem->GetElement();
396 if(DEBUG)printf("ajout elem OOOO premiere fois\n");
397 gdcmDictEntry * tagZ = new gdcmDictEntry(gr, 0x0000, "UL");
398 elemZPrec = new gdcmElValue(tagZ); // on le cree
399 elemZPrec->SetLength(4);
400 Add(elemZPrec); // On l'accroche à sa place
403 if(DEBUG)printf("Pas d'ajout elem OOOO premiere fois\n");
406 if(DEBUG)printf("init-1 lgr (%d) pour gr %04x\n",lgrCalcGroupe, gr);
409 for (tag = ++tagHt.begin();
414 gr = elem->GetGroup();
415 el = elem->GetElement();
417 if ( (gr != grCourant) /*&& // On arrive sur un nv Groupe
418 (el != 0xfffe) */ ) {
421 gdcmDictEntry * tagZ = new gdcmDictEntry(gr, 0x0000, "UL");
422 elemZ = new gdcmElValue(tagZ); // on le cree
424 Add(elemZ); // On l'accroche à sa place
425 if(DEBUG)printf("ajout elem OOOO pour gr %04x\n",gr);
428 if(DEBUG)printf("maj elmeZ\n");
432 fock << lgrCalcGroupe;
433 //sprintf(str_lgrCalcGroupe,"%d",lgrCalcGroupe);
434 elemZPrec->SetValue(fock.str());
435 if(DEBUG)printf("ecriture lgr (%d, %s) pour gr %04x\n",lgrCalcGroupe, fock.str().c_str(), grCourant);
436 if(DEBUG)printf ("%04x %04x [%s]\n",elemZPrec->GetGroup(), elemZPrec->GetElement(),elemZPrec->GetValue().c_str());
437 if(DEBUG)cout << "Addresse elemZPrec " << elemZPrec<< endl;
441 if(DEBUG)printf("init-2 lgr (%d) pour gr %04x\n",lgrCalcGroupe, gr);
442 } else { // On n'EST PAS sur un nv Groupe
443 lgrCalcGroupe += 2 + 2 + 4 + elem->GetLength(); // Gr + Num + Lgr + LgrElem
444 if(DEBUG)printf("increment (%d) el %04x-->lgr (%d) pour gr %04x\n",elem->GetLength(), el, lgrCalcGroupe, gr);
448 // Si on fait de l'implicit VR little Endian
449 // (pour moins se fairche sur processeur INTEL)
450 // penser a forcer le TRANSFERT SYNTAX UID
452 // supprime par rapport à Write
453 //SetElValueByNumber(implicitVRTransfertSyntax, 0x0002, 0x0010);
454 //SetElValueLengthByNumber(18, 0x0002, 0x0010); // Le 0 de fin de chaine doit etre stocké, dans ce cas
456 // restent à tester les echecs en écriture (apres chaque fwrite)
458 for (TagElValueHT::iterator tag2 = tagHt.begin();
462 gr = tag2->second->GetGroup();
463 // saut des groupes speciaux DICOM V3
464 if (gr < 0x0008) continue; // ajouté par rapport à Write
465 // saut des groupes impairs
466 if (gr %2) continue; // ajouté par rapport à Write
468 el = tag2->second->GetElement();
469 lgr = tag2->second->GetLength();
470 val = tag2->second->GetValue().c_str();
471 vr = tag2->second->GetVR();
473 fwrite ( &gr,(size_t)2 ,(size_t)1 ,_fp); //group
474 fwrite ( &el,(size_t)2 ,(size_t)1 ,_fp); //element
476 // si on n'est pas en IMPLICIT VR voir pb (lgr + VR)
478 fwrite ( &lgr,(size_t)4 ,(size_t)1 ,_fp); //lgr
480 tokens.erase(tokens.begin(),tokens.end());
481 Tokenize (tag2->second->GetValue(), tokens, "\\");
483 if (vr == "US" || vr == "SS") {
485 for (unsigned int i=0; i<tokens.size();i++) {
486 val_uint16 = atoi(tokens[i].c_str());
488 fwrite ( ptr,(size_t)2 ,(size_t)1 ,_fp);
493 if (vr == "UL" || vr == "SL") {
494 for (unsigned int i=0; i<tokens.size();i++) {
495 val_uint32 = atoi(tokens[i].c_str());
497 fwrite ( ptr,(size_t)4 ,(size_t)1 ,_fp);
503 // Les pixels ne sont pas chargés dans l'element !
504 if ((gr == 0x7fe0) && (el == 0x0010) ) break;
506 fwrite ( val,(size_t)lgr ,(size_t)1 ,_fp); //valeur Elem