1 // $Header: /cvs/public/gdcm/src/Attic/gdcmElValSet.cxx,v 1.17 2003/03/12 21:33:20 frog Exp $
4 #include "gdcmElValSet.h"
8 static void Tokenize (const string& str, vector<string>& tokens, const string& delimiters = " ");
11 TagElValueHT & gdcmElValSet::GetTagHt(void) {
15 void gdcmElValSet::Add(gdcmElValue * newElValue) {
16 tagHt [newElValue->GetKey()] = newElValue;
17 NameHt[newElValue->GetName()] = newElValue;
20 void gdcmElValSet::Print(ostream & os) {
21 for (TagElValueHT::iterator tag = tagHt.begin();
24 os << tag->first << ": ";
25 os << "[" << tag->second->GetValue() << "]";
26 os << "[" << tag->second->GetName() << "]";
27 os << "[" << tag->second->GetVR() << "]" << endl;
31 void gdcmElValSet::PrintByName(ostream & os) {
32 for (TagElValueNameHT::iterator tag = NameHt.begin();
35 os << tag->first << ": ";
36 os << "[" << tag->second->GetValue() << "]";
37 os << "[" << tag->second->GetKey() << "]";
38 os << "[" << tag->second->GetVR() << "]" << endl;
42 gdcmElValue* gdcmElValSet::GetElementByNumber(guint32 group, guint32 element) {
43 TagKey key = gdcmDictEntry::TranslateToKey(group, element);
44 if ( ! tagHt.count(key))
45 return (gdcmElValue*)0;
46 if (tagHt.count(key) > 1)
47 dbg.Verbose(0, "gdcmElValSet::GetElementByNumber",
48 "multiple entries for this key (FIXME) !");
49 return tagHt.find(key)->second;
52 gdcmElValue* gdcmElValSet::GetElementByName(string TagName) {
53 if ( ! NameHt.count(TagName))
54 return (gdcmElValue*)0;
55 if (NameHt.count(TagName) > 1)
56 dbg.Verbose(0, "gdcmElValSet::GetElement",
57 "multipe entries for this key (FIXME) !");
58 return NameHt.find(TagName)->second;
61 string gdcmElValSet::GetElValueByNumber(guint32 group, guint32 element) {
62 TagKey key = gdcmDictEntry::TranslateToKey(group, element);
63 if ( ! tagHt.count(key))
64 return "gdcm::Unfound";
65 if (tagHt.count(key) > 1)
66 dbg.Verbose(0, "gdcmElValSet::GetElValueByNumber",
67 "multiple entries for this key (FIXME) !");
68 return tagHt.find(key)->second->GetValue();
71 string gdcmElValSet::GetElValueByName(string TagName) {
72 if ( ! NameHt.count(TagName))
73 return "gdcm::Unfound";
74 if (NameHt.count(TagName) > 1)
75 dbg.Verbose(0, "gdcmElValSet::GetElValue",
76 "multipe entries for this key (FIXME) !");
77 return NameHt.find(TagName)->second->GetValue();
80 int gdcmElValSet::SetElValueByNumber(string content,
81 guint32 group, guint32 element) {
82 TagKey key = gdcmDictEntry::TranslateToKey(group, element);
83 if ( ! tagHt.count(key))
85 if (tagHt.count(key) > 1) {
86 dbg.Verbose(0, "gdcmElValSet::SetElValueByNumber",
87 "multiple entries for this key (FIXME) !");
90 tagHt[key]->SetValue(content);
92 // Question : m à j LgrElem ?
93 tagHt[key]->SetLength(strlen(content.c_str()));
95 // FIXME should we really update the element length ?
96 tagHt[key]->SetLength(content.length());
101 int gdcmElValSet::SetElValueByName(string content, string TagName) {
102 if ( ! NameHt.count(TagName))
104 if (NameHt.count(TagName) > 1) {
105 dbg.Verbose(0, "gdcmElValSet::SetElValueByName",
106 "multipe entries for this key (FIXME) !");
109 NameHt.find(TagName)->second->SetValue(content);
110 NameHt.find(TagName)->second->SetLength(strlen(content.c_str()));
115 int gdcmElValSet::SetElValueLengthByNumber(guint32 l,
116 guint32 group, guint32 element) {
117 TagKey key = gdcmDictEntry::TranslateToKey(group, element);
118 if ( ! tagHt.count(key))
120 if (tagHt.count(key) > 1) {
121 dbg.Verbose(0, "gdcmElValSet::SetElValueLengthByNumber",
122 "multiple entries for this key (FIXME) !");
125 // FIXME JPR: comments in English please !
127 tagHt[key]->SetLength(l);
132 int gdcmElValSet::SetElValueLengthByName(guint32 l, string TagName) {
133 if ( ! NameHt.count(TagName))
135 if (NameHt.count(TagName) > 1) {
136 dbg.Verbose(0, "gdcmElValSet::SetElValueByName",
137 "multipe entries for this key (FIXME) !");
140 NameHt.find(TagName)->second->SetLength(l);
145 int gdcmElValSet::Write(FILE * _fp) {
147 // ATTENTION : fonction non terminée (commitée a titre de precaution)
158 vector<string> tokens;
161 char str_lgrCalcGroupe[10];
163 string implicitVRTransfertSyntax = "1.2.840.10008.1.2";
165 // Utilisées pour le calcul Group Length
167 guint32 lgrCalcGroupe=0;
168 gdcmElValue *elem, *elemZ, *elemZPrec;
169 guint16 grCourant = 0;
172 // Comment pourrait-on tester si on est TrueDicom ou non ,
173 // (FileType est un champ de gdcmHeader ...)
176 // On parcourt la table pour recalculer la longueur des 'elements 0x0000'
177 // au cas ou un tag ai été ajouté par rapport à ce qui a été lu
178 // dans l'image native
180 // cf : code IdDcmWriteFile dans libido/src/dcmwrite.c
182 if (0) // Risque de pb dans le calcul des lgr de chaque groupe. On le saute pour le moment!
184 for (TagElValueHT::iterator tag = tagHt.begin();
189 printf("gr %04x el %04x lgr %d\n",elem->GetGroup(), elem->GetElement(), elem->GetLength());
191 if ( (elem->GetGroup() != grCourant) &&
192 (elem->GetGroup() != 0xfffe) ) { // On arrive sur un nv Groupe
194 printf("Nouv Groupegr %04x el %04x \n",elem->GetGroup(), elem->GetElement());
198 if(elemZ->GetElement() != 0x0000) { // pas d'element 'Lgr groupe'
200 gdcmDictEntry * tagZ = new gdcmDictEntry(grCourant, 0x0000, "UL");
201 elemZ = new gdcmElValue(tagZ); // on le cree
203 Add(elemZ); // On l'accroche à sa place
207 //sprintf(str_lgrCalcGroupe,"%d",lgrCalcGroupe);
208 elemZPrec->SetValue(str_lgrCalcGroupe);
213 lgrCalcGroupe = 12; //2 + 2 + 4 + 4; // Gr + Num + Lgr + LgrGroupe
214 printf ("lgrCalcGroupe %d\n",lgrCalcGroupe);
217 grCourant = elem->GetGroup();
219 } else { // On n'EST PAS sur un nv Groupe
221 printf ("lgrCalcGroupe avant : %d LgrElem %d\n",lgrCalcGroupe,elem->GetLength());
223 lgrCalcGroupe += 2 + 2 + 4 + elem->GetLength(); // Gr + Num + Lgr + LgrElem
225 printf ("lgrCalcGroupe apres %d\n",lgrCalcGroupe);
229 // Si on fait de l'implicit VR little Endian
230 // (pour moins se fairche sur processeur INTEL)
231 // penser a forcer le TRANSFERT SYNTAX UID
233 SetElValueByNumber(implicitVRTransfertSyntax, 0x0002, 0x0010);
234 SetElValueLengthByNumber(18, 0x0002, 0x0010); // Le 0 de fin de chaine doit etre stocké, dans ce cas
236 // restent à tester les echecs en écriture (apres chaque fwrite)
238 for (TagElValueHT::iterator tag2 = tagHt.begin();
242 gr = tag2->second->GetGroup();
243 el = tag2->second->GetElement();
244 lgr = tag2->second->GetLength();
245 val = tag2->second->GetValue().c_str();
246 vr = tag2->second->GetVR();
248 fwrite ( &gr,(size_t)2 ,(size_t)1 ,_fp); //group
249 fwrite ( &el,(size_t)2 ,(size_t)1 ,_fp); //element
251 //fwrite ( vr,(size_t)2 ,(size_t)1 ,_fp); //VR
253 // si on n'est pas en IMPLICIT VR voir pb (lgr + VR)
255 fwrite ( &lgr,(size_t)4 ,(size_t)1 ,_fp); //lgr
257 tokens.erase(tokens.begin(),tokens.end());
258 Tokenize (tag2->second->GetValue(), tokens, "\\");
260 //printf ("%04x %04x [%s] : [%s]\n",gr, el, vr.c_str(), val);
261 //if (tokens.size() > 1) { printf ("size : %d\n",tokens.size());}
264 if (vr == "US" || vr == "SS") {
266 val_int16 = atoi(val);
268 fwrite ( ptr,(size_t)2 ,(size_t)1 ,_fp);
272 for (unsigned int i=0; i<tokens.size();i++) {
273 val_uint16 = atoi(tokens[i].c_str());
275 fwrite ( ptr,(size_t)2 ,(size_t)1 ,_fp);
280 if (vr == "UL" || vr == "SL") {
282 val_int32 = atoi(val);
284 fwrite ( ptr,(size_t)4 ,(size_t)1 ,_fp);
289 for (unsigned int i=0; i<tokens.size();i++) {
290 val_uint32 = atoi(tokens[i].c_str());
292 fwrite ( ptr,(size_t)4 ,(size_t)1 ,_fp);
298 // Les pixels ne sont pas chargés dans l'element !
299 if ((gr == 0x7fe0) && (el == 0x0010) ) break;
301 fwrite ( val,(size_t)lgr ,(size_t)1 ,_fp); //valeur Elem
310 int gdcmElValSet::WriteAcr(FILE * _fp) {
313 // ATTENTION : fonction non terminée (commitée a titre de precaution)
314 // ATTENTION : fusioner le code avec celui de lValSet::Write
326 vector<string> tokens;
329 char str_lgrCalcGroupe[10];
331 //string implicitVRTransfertSyntax = "1.2.840.10008.1.2"; // supprime par rapport à Write
333 // Utilisées pour le calcul Group Length
335 guint32 lgrCalcGroupe=0;
336 gdcmElValue *elem, *elemZ, *elemZPrec;
337 guint16 grCourant = 0;
340 // Comment pourrait-on tester si on est TrueDicom ou non ,
341 // (FileType est un champ de gdcmHeader ...)
344 // On parcourt la table pour recalculer la longueur des 'elements 0x0000'
345 // au cas ou un tag ai été ajouté par rapport à ce qui a été lu
346 // dans l'image native
348 // cf : code IdDcmWriteFile dans libido/src/dcmwrite.c
350 if (1) // Risque de pb dans le calcul des lgr de chaque groupe. On le saute pour le moment!
352 for (TagElValueHT::iterator tag = tagHt.begin();
357 //printf("gr %04x el %04x lgr %d\n",elem->GetGroup(), elem->GetElement(), elem->GetLength());
359 if ( (elem->GetGroup() != grCourant) &&
360 (elem->GetGroup() != 0xfffe) ) { // On arrive sur un nv Groupe
362 //printf("Nouv Groupegr %04x el %04x \n",elem->GetGroup(), elem->GetElement());
366 if(elemZ->GetElement() != 0x0000) { // pas d'element 'Lgr groupe'
368 gdcmDictEntry * tagZ = new gdcmDictEntry(grCourant, 0x0000, "UL");
369 elemZ = new gdcmElValue(tagZ); // on le cree
371 Add(elemZ); // On l'accroche à sa place
375 //sprintf(str_lgrCalcGroupe,"%d",lgrCalcGroupe);
376 elemZPrec->SetValue(str_lgrCalcGroupe);
381 lgrCalcGroupe = 12; //2 + 2 + 4 + 4; // Gr + Num + Lgr + LgrGroupe
382 //printf ("lgrCalcGroupe %d\n",lgrCalcGroupe);
385 grCourant = elem->GetGroup();
387 } else { // On n'EST PAS sur un nv Groupe
389 //printf ("lgrCalcGroupe avant : %d LgrElem %d\n",lgrCalcGroupe,elem->GetLength());
391 lgrCalcGroupe += 2 + 2 + 4 + elem->GetLength(); // Gr + Num + Lgr + LgrElem
393 //printf ("lgrCalcGroupe apres %d\n",lgrCalcGroupe);
397 // Si on fait de l'implicit VR little Endian
398 // (pour moins se fairche sur processeur INTEL)
399 // penser a forcer le TRANSFERT SYNTAX UID
401 // supprime par rapport à Write
402 //SetElValueByNumber(implicitVRTransfertSyntax, 0x0002, 0x0010);
403 //SetElValueLengthByNumber(18, 0x0002, 0x0010); // Le 0 de fin de chaine doit etre stocké, dans ce cas
405 // restent à tester les echecs en écriture (apres chaque fwrite)
407 for (TagElValueHT::iterator tag2 = tagHt.begin();
411 gr = tag2->second->GetGroup();
412 // saut des groupes speciaux DICOM V3
413 if (gr < 0x0008) continue; // ajouté par rapport à Write
414 // saut des groupes impairs
415 if (gr %2) continue; // ajouté par rapport à Write
417 el = tag2->second->GetElement();
418 lgr = tag2->second->GetLength();
419 val = tag2->second->GetValue().c_str();
420 vr = tag2->second->GetVR();
422 fwrite ( &gr,(size_t)2 ,(size_t)1 ,_fp); //group
423 fwrite ( &el,(size_t)2 ,(size_t)1 ,_fp); //element
425 // si on n'est pas en IMPLICIT VR voir pb (lgr + VR)
427 fwrite ( &lgr,(size_t)4 ,(size_t)1 ,_fp); //lgr
429 tokens.erase(tokens.begin(),tokens.end());
430 Tokenize (tag2->second->GetValue(), tokens, "\\");
432 if (vr == "US" || vr == "SS") {
434 for (unsigned int i=0; i<tokens.size();i++) {
435 val_uint16 = atoi(tokens[i].c_str());
437 fwrite ( ptr,(size_t)2 ,(size_t)1 ,_fp);
442 if (vr == "UL" || vr == "SL") {
443 for (unsigned int i=0; i<tokens.size();i++) {
444 val_uint32 = atoi(tokens[i].c_str());
446 fwrite ( ptr,(size_t)4 ,(size_t)1 ,_fp);
452 // Les pixels ne sont pas chargés dans l'element !
453 if ((gr == 0x7fe0) && (el == 0x0010) ) break;
455 fwrite ( val,(size_t)lgr ,(size_t)1 ,_fp); //valeur Elem
464 // mettre ça dans une bibliothèque d'utilitaires ?
467 static void Tokenize (const string& str, vector<string>& tokens, const string& delimiters = " ") {
468 string::size_type lastPos = str.find_first_not_of(delimiters,0);
469 string::size_type pos = str.find_first_of(delimiters,lastPos);
470 while (string::npos != pos || string::npos != lastPos) {
471 tokens.push_back(str.substr(lastPos, pos - lastPos));
472 lastPos = str.find_first_not_of(delimiters, pos);
473 pos = str.find_first_of(delimiters, lastPos);