]> Creatis software - gdcm.git/blob - src/gdcmElValSet.cxx
* gdcmPython/__init__.py fix of GDCM_DICT_PATH which was not
[gdcm.git] / src / gdcmElValSet.cxx
1 // $Id: gdcmElValSet.cxx,v 1.18 2003/03/12 23:38:58 frog Exp $
2
3 #include "gdcmUtil.h"
4 #include "gdcmElValSet.h"
5
6 TagElValueHT & gdcmElValSet::GetTagHt(void) {
7         return tagHt;
8 }
9
10 void gdcmElValSet::Add(gdcmElValue * newElValue) {
11         tagHt [newElValue->GetKey()]  = newElValue;
12         NameHt[newElValue->GetName()] = newElValue;
13 }
14
15 void gdcmElValSet::Print(ostream & os) {
16         for (TagElValueHT::iterator tag = tagHt.begin();
17                   tag != tagHt.end();
18                   ++tag){
19                 os << tag->first << ": ";
20                 os << "[" << tag->second->GetValue() << "]";
21                 os << "[" << tag->second->GetName()  << "]";
22                 os << "[" << tag->second->GetVR()    << "]" << endl;
23         }
24
25
26 void gdcmElValSet::PrintByName(ostream & os) {
27         for (TagElValueNameHT::iterator tag = NameHt.begin();
28                   tag != NameHt.end();
29                   ++tag){
30                 os << tag->first << ": ";
31                 os << "[" << tag->second->GetValue() << "]";
32                 os << "[" << tag->second->GetKey()   << "]";
33                 os << "[" << tag->second->GetVR()    << "]" << endl;
34         }
35 }
36
37 gdcmElValue* gdcmElValSet::GetElementByNumber(guint32 group, guint32 element) {
38         TagKey key = gdcmDictEntry::TranslateToKey(group, element);
39         if ( ! tagHt.count(key))
40                 return (gdcmElValue*)0;
41         if (tagHt.count(key) > 1)
42                 dbg.Verbose(0, "gdcmElValSet::GetElementByNumber",
43                             "multiple entries for this key (FIXME) !");
44         return tagHt.find(key)->second;
45 }
46
47 gdcmElValue* gdcmElValSet::GetElementByName(string TagName) {
48    if ( ! NameHt.count(TagName))
49       return (gdcmElValue*)0;
50    if (NameHt.count(TagName) > 1)
51       dbg.Verbose(0, "gdcmElValSet::GetElement",
52                   "multipe entries for this key (FIXME) !");
53    return NameHt.find(TagName)->second;
54 }
55
56 string gdcmElValSet::GetElValueByNumber(guint32 group, guint32 element) {
57         TagKey key = gdcmDictEntry::TranslateToKey(group, element);
58         if ( ! tagHt.count(key))
59                 return "gdcm::Unfound";
60         if (tagHt.count(key) > 1)
61                 dbg.Verbose(0, "gdcmElValSet::GetElValueByNumber",
62                             "multiple entries for this key (FIXME) !");
63         return tagHt.find(key)->second->GetValue();
64 }
65
66 string gdcmElValSet::GetElValueByName(string TagName) {
67         if ( ! NameHt.count(TagName))
68                 return "gdcm::Unfound";
69         if (NameHt.count(TagName) > 1)
70                 dbg.Verbose(0, "gdcmElValSet::GetElValue",
71                             "multipe entries for this key (FIXME) !");
72         return NameHt.find(TagName)->second->GetValue();
73 }
74
75 int gdcmElValSet::SetElValueByNumber(string content,
76                                      guint32 group, guint32 element) {
77         TagKey key = gdcmDictEntry::TranslateToKey(group, element);
78         if ( ! tagHt.count(key))
79                 return 0;
80         if (tagHt.count(key) > 1) {
81                 dbg.Verbose(0, "gdcmElValSet::SetElValueByNumber",
82                             "multiple entries for this key (FIXME) !");
83                 return (0); 
84         }                                      
85         tagHt[key]->SetValue(content);
86
87         // Question : m à j LgrElem ?
88         tagHt[key]->SetLength(strlen(content.c_str()));  
89
90         // FIXME should we really update the element length ?
91         tagHt[key]->SetLength(content.length());         
92
93         return(1);              
94 }
95
96 int gdcmElValSet::SetElValueByName(string content, string TagName) {
97         if ( ! NameHt.count(TagName))
98                 return 0;
99         if (NameHt.count(TagName) > 1) {
100                 dbg.Verbose(0, "gdcmElValSet::SetElValueByName",
101                             "multipe entries for this key (FIXME) !");
102                 return 0;
103         }
104         NameHt.find(TagName)->second->SetValue(content);
105         NameHt.find(TagName)->second->SetLength(strlen(content.c_str()));        
106         return(1);              
107 }
108
109
110 int gdcmElValSet::SetElValueLengthByNumber(guint32 l,
111                                            guint32 group, guint32 element) {
112         TagKey key = gdcmDictEntry::TranslateToKey(group, element);
113         if ( ! tagHt.count(key))
114                 return 0;
115         if (tagHt.count(key) > 1) {
116                 dbg.Verbose(0, "gdcmElValSet::SetElValueLengthByNumber",
117                             "multiple entries for this key (FIXME) !");
118                 return (0); 
119         }                                      
120    // FIXME JPR: comments in English please !
121         // m à j LgrElem 
122         tagHt[key]->SetLength(l);        
123         return(1);              
124 }
125
126
127 int gdcmElValSet::SetElValueLengthByName(guint32 l, string TagName) {
128         if ( ! NameHt.count(TagName))
129                 return 0;
130         if (NameHt.count(TagName) > 1) {
131                 dbg.Verbose(0, "gdcmElValSet::SetElValueByName",
132                             "multipe entries for this key (FIXME) !");
133                 return 0;
134         }
135         NameHt.find(TagName)->second->SetLength(l);      
136         return(1);              
137 }
138
139
140 int gdcmElValSet::Write(FILE * _fp) {
141
142 // ATTENTION : fonction non terminée (commitée a titre de precaution)
143
144         guint16 gr, el;
145         guint32 lgr;
146         const char * val;
147         string vr;
148         guint32 val_uint32;
149         gint32  val_int32;
150         guint16 val_uint16;
151         gint16  val_int16;
152         
153         vector<string> tokens;
154         
155         void *ptr;
156         char str_lgrCalcGroupe[10];
157         
158         string implicitVRTransfertSyntax = "1.2.840.10008.1.2";
159         
160         // Utilisées pour le calcul Group Length
161         int deja = 0;
162         guint32 lgrCalcGroupe=0;
163         gdcmElValue *elem, *elemZ, *elemZPrec;
164         guint16 grCourant = 0;
165         
166         // Question :
167         // Comment pourrait-on tester si on est TrueDicom ou non ,
168         // (FileType est un champ de gdcmHeader ...)
169         //
170
171         // On parcourt la table pour recalculer la longueur des 'elements 0x0000'
172         // au cas ou un tag ai été ajouté par rapport à ce qui a été lu
173         // dans l'image native
174         //
175         // cf : code IdDcmWriteFile dans libido/src/dcmwrite.c
176                 
177         if (0)  // Risque de pb dans le calcul des lgr de chaque groupe. On le saute pour le moment!
178         
179         for (TagElValueHT::iterator tag = tagHt.begin();
180                   tag != tagHt.end();
181                   ++tag){
182
183                 elem = tag->second;
184                 printf("gr %04x el %04x lgr %d\n",elem->GetGroup(), elem->GetElement(), elem->GetLength());
185         
186                 if ( (elem->GetGroup() != grCourant) &&   
187                          (elem->GetGroup() != 0xfffe)   ) {     // On arrive sur un nv Groupe
188                          
189                 printf("Nouv Groupegr %04x el %04x \n",elem->GetGroup(), elem->GetElement());
190
191                         elemZ = elem; 
192                          
193                         if(elemZ->GetElement() != 0x0000) {     // pas d'element 'Lgr groupe'
194                                 // On crée
195                                 gdcmDictEntry * tagZ = new gdcmDictEntry(grCourant, 0x0000, "UL");
196                                 elemZ = new gdcmElValue(tagZ); // on le cree
197                                 elemZ->SetLength(4);
198                                 Add(elemZ);                                      // On l'accroche à sa place    
199                         }       
200                         
201                         if (deja) {
202                                 //sprintf(str_lgrCalcGroupe,"%d",lgrCalcGroupe);
203                                 elemZPrec->SetValue(str_lgrCalcGroupe);
204                                 lgrCalcGroupe = 0;
205                         }
206                         deja = 1;
207                         
208                         lgrCalcGroupe =  12; //2 + 2 + 4 + 4; // Gr + Num + Lgr + LgrGroupe
209                         printf ("lgrCalcGroupe %d\n",lgrCalcGroupe);
210                         
211                         elemZPrec = elemZ;
212                         grCourant = elem->GetGroup();
213                                                         
214                 } else {                // On n'EST PAS sur un nv Groupe
215                 
216                         printf ("lgrCalcGroupe avant : %d LgrElem %d\n",lgrCalcGroupe,elem->GetLength());
217
218                         lgrCalcGroupe += 2 + 2 + 4 + elem->GetLength();  // Gr + Num + Lgr + LgrElem 
219                         
220                         printf ("lgrCalcGroupe apres %d\n",lgrCalcGroupe);
221                 }               
222         }
223         
224         // Si on fait de l'implicit VR little Endian 
225         // (pour moins se fairche sur processeur INTEL)
226         // penser a forcer le TRANSFERT SYNTAX UID
227                                 
228         SetElValueByNumber(implicitVRTransfertSyntax, 0x0002, 0x0010);  
229         SetElValueLengthByNumber(18, 0x0002, 0x0010);  // Le 0 de fin de chaine doit etre stocké, dans ce cas   
230                 
231         // restent à tester les echecs en écriture (apres chaque fwrite)
232         
233         for (TagElValueHT::iterator tag2 = tagHt.begin();
234                   tag2 != tagHt.end();
235                   ++tag2){
236                 
237                 gr =  tag2->second->GetGroup();
238                 el =  tag2->second->GetElement();
239                 lgr = tag2->second->GetLength();
240                 val = tag2->second->GetValue().c_str();
241                 vr =  tag2->second->GetVR();
242                         
243                 fwrite ( &gr,(size_t)2 ,(size_t)1 ,_fp);        //group
244                 fwrite ( &el,(size_t)2 ,(size_t)1 ,_fp);        //element
245                 
246                 //fwrite ( vr,(size_t)2 ,(size_t)1 ,_fp);       //VR
247                 
248                 // si on n'est pas en IMPLICIT VR voir pb (lgr  + VR)
249                 
250                 fwrite ( &lgr,(size_t)4 ,(size_t)1 ,_fp);               //lgr
251                 
252                 tokens.erase(tokens.begin(),tokens.end());
253                 Tokenize (tag2->second->GetValue(), tokens, "\\");
254                 
255                 //printf ("%04x %04x [%s] : [%s]\n",gr, el, vr.c_str(), val);
256                 //if (tokens.size() > 1) { printf ("size : %d\n",tokens.size());}
257                 
258                 
259                 if (vr == "US" || vr == "SS") {
260                         /*
261                         val_int16 = atoi(val);
262                         ptr = &val_int16;
263                         fwrite ( ptr,(size_t)2 ,(size_t)1 ,_fp);        
264                         continue;
265                         */
266                         
267                         for (unsigned int i=0; i<tokens.size();i++) {
268                                 val_uint16 = atoi(tokens[i].c_str());           
269                                 ptr = &val_uint16;
270                                 fwrite ( ptr,(size_t)2 ,(size_t)1 ,_fp);
271                         }
272                         continue;
273                         
274                 }
275                 if (vr == "UL" || vr == "SL") {
276                         /*
277                         val_int32 = atoi(val);
278                         ptr = &val_int32;
279                         fwrite ( ptr,(size_t)4 ,(size_t)1 ,_fp);        
280                         continue;
281                         */
282                         
283                         
284                         for (unsigned int i=0; i<tokens.size();i++) {
285                                 val_uint32 = atoi(tokens[i].c_str());           
286                                 ptr = &val_uint32;
287                                 fwrite ( ptr,(size_t)4 ,(size_t)1 ,_fp);
288                         }
289                         continue;                               
290                         
291                 }       
292                 
293                 // Les pixels ne sont pas chargés dans l'element !
294                 if ((gr == 0x7fe0) && (el == 0x0010) ) break;
295
296                 fwrite ( val,(size_t)lgr ,(size_t)1 ,_fp); //valeur Elem
297         }
298                 
299         return(1);
300 }
301
302
303
304
305 int gdcmElValSet::WriteAcr(FILE * _fp) {
306
307
308 // ATTENTION : fonction non terminée (commitée a titre de precaution)
309 // ATTENTION : fusioner le code avec celui de lValSet::Write
310
311
312         guint16 gr, el;
313         guint32 lgr;
314         const char * val;
315         string vr;
316         guint32 val_uint32;
317         gint32  val_int32;
318         guint16 val_uint16;
319         gint16  val_int16;
320         
321         vector<string> tokens;
322         
323         void *ptr;
324         char str_lgrCalcGroupe[10];
325         
326         //string implicitVRTransfertSyntax = "1.2.840.10008.1.2"; // supprime par rapport à Write
327         
328         // Utilisées pour le calcul Group Length
329         int deja = 0;
330         guint32 lgrCalcGroupe=0;
331         gdcmElValue *elem, *elemZ, *elemZPrec;
332         guint16 grCourant = 0;
333         
334         // Question :
335         // Comment pourrait-on tester si on est TrueDicom ou non ,
336         // (FileType est un champ de gdcmHeader ...)
337         //
338
339         // On parcourt la table pour recalculer la longueur des 'elements 0x0000'
340         // au cas ou un tag ai été ajouté par rapport à ce qui a été lu
341         // dans l'image native
342         //
343         // cf : code IdDcmWriteFile dans libido/src/dcmwrite.c
344                 
345         if (1)  // Risque de pb dans le calcul des lgr de chaque groupe. On le saute pour le moment!
346         
347         for (TagElValueHT::iterator tag = tagHt.begin();
348                   tag != tagHt.end();
349                   ++tag){
350
351                 elem = tag->second;
352                 //printf("gr %04x el %04x lgr %d\n",elem->GetGroup(), elem->GetElement(), elem->GetLength());
353         
354                 if ( (elem->GetGroup() != grCourant) &&   
355                          (elem->GetGroup() != 0xfffe)   ) {     // On arrive sur un nv Groupe
356                          
357                 //printf("Nouv Groupegr %04x el %04x \n",elem->GetGroup(), elem->GetElement());
358
359                         elemZ = elem; 
360                          
361                         if(elemZ->GetElement() != 0x0000) {     // pas d'element 'Lgr groupe'
362                                 // On crée
363                                 gdcmDictEntry * tagZ = new gdcmDictEntry(grCourant, 0x0000, "UL");
364                                 elemZ = new gdcmElValue(tagZ); // on le cree
365                                 elemZ->SetLength(4);
366                                 Add(elemZ);                                      // On l'accroche à sa place    
367                         }       
368                         
369                         if (deja) {
370                                 //sprintf(str_lgrCalcGroupe,"%d",lgrCalcGroupe);
371                                 elemZPrec->SetValue(str_lgrCalcGroupe);
372                                 lgrCalcGroupe = 0;
373                         }
374                         deja = 1;
375                         
376                         lgrCalcGroupe =  12; //2 + 2 + 4 + 4; // Gr + Num + Lgr + LgrGroupe
377                         //printf ("lgrCalcGroupe %d\n",lgrCalcGroupe);
378                         
379                         elemZPrec = elemZ;
380                         grCourant = elem->GetGroup();
381                                                         
382                 } else {                // On n'EST PAS sur un nv Groupe
383                 
384                         //printf ("lgrCalcGroupe avant : %d LgrElem %d\n",lgrCalcGroupe,elem->GetLength());
385
386                         lgrCalcGroupe += 2 + 2 + 4 + elem->GetLength();  // Gr + Num + Lgr + LgrElem 
387                         
388                         //printf ("lgrCalcGroupe apres %d\n",lgrCalcGroupe);
389                 }               
390         }
391         
392         // Si on fait de l'implicit VR little Endian 
393         // (pour moins se fairche sur processeur INTEL)
394         // penser a forcer le TRANSFERT SYNTAX UID
395         
396         // supprime par rapport à Write         
397         //SetElValueByNumber(implicitVRTransfertSyntax, 0x0002, 0x0010);        
398         //SetElValueLengthByNumber(18, 0x0002, 0x0010);  // Le 0 de fin de chaine doit etre stocké, dans ce cas 
399                 
400         // restent à tester les echecs en écriture (apres chaque fwrite)
401         
402         for (TagElValueHT::iterator tag2 = tagHt.begin();
403                   tag2 != tagHt.end();
404                   ++tag2){
405
406                 gr =  tag2->second->GetGroup();
407                                                 // saut des groupes speciaux DICOM V3
408                 if (gr < 0x0008) continue;      // ajouté par rapport à Write
409                                                 // saut des groupes impairs
410                 if (gr %2)       continue;      // ajouté par rapport à Write
411                 
412                 el =  tag2->second->GetElement();
413                 lgr = tag2->second->GetLength();
414                 val = tag2->second->GetValue().c_str();
415                 vr =  tag2->second->GetVR();
416                         
417                 fwrite ( &gr,(size_t)2 ,(size_t)1 ,_fp);        //group
418                 fwrite ( &el,(size_t)2 ,(size_t)1 ,_fp);        //element
419                                 
420                 // si on n'est pas en IMPLICIT VR voir pb (lgr  + VR)
421                 
422                 fwrite ( &lgr,(size_t)4 ,(size_t)1 ,_fp);               //lgr
423                 
424                 tokens.erase(tokens.begin(),tokens.end());
425                 Tokenize (tag2->second->GetValue(), tokens, "\\");
426                 
427                 if (vr == "US" || vr == "SS") {
428
429                         for (unsigned int i=0; i<tokens.size();i++) {
430                                 val_uint16 = atoi(tokens[i].c_str());           
431                                 ptr = &val_uint16;
432                                 fwrite ( ptr,(size_t)2 ,(size_t)1 ,_fp);
433                         }
434                         continue;
435                         
436                 }
437                 if (vr == "UL" || vr == "SL") {
438                         for (unsigned int i=0; i<tokens.size();i++) {
439                                 val_uint32 = atoi(tokens[i].c_str());           
440                                 ptr = &val_uint32;
441                                 fwrite ( ptr,(size_t)4 ,(size_t)1 ,_fp);
442                         }
443                         continue;                               
444                         
445                 }       
446                 
447                 // Les pixels ne sont pas chargés dans l'element !
448                 if ((gr == 0x7fe0) && (el == 0x0010) ) break;
449
450                 fwrite ( val,(size_t)lgr ,(size_t)1 ,_fp); //valeur Elem
451         }
452                 
453         return(1);
454 }