]> Creatis software - gdcm.git/blob - src/gdcmHeader2.cxx
* removal of file gdcmHeader2.cxx
[gdcm.git] / src / gdcmHeader2.cxx
1 // gdcmHeader2.cxx
2 //-----------------------------------------------------------------------------
3 #include "gdcmUtil.h"
4 #include "gdcmHeader.h"
5 #include "gdcmTS.h"
6 #ifdef GDCM_NO_ANSI_STRING_STREAM
7 #  include <strstream>
8 #  define  ostringstream ostrstream
9 # else
10 #  include <sstream>
11 #endif
12
13 #include <iomanip> // for std::ios::left, ...
14
15 //-----------------------------------------------------------------------------
16 // Print
17 /**
18  * \ingroup gdcmHeader
19  * \brief prints the Dicom Elements of the gdcmHeader
20  *        using both H table and Chained List
21  * @param   os The output stream to be written to.  
22  */
23 /*void gdcmHeader::Print(std::ostream & os) {
24
25    size_t o;
26    unsigned short int g, e;
27    TSKey v;
28    std::string d2;
29    gdcmTS * ts = gdcmGlobal::GetTS();
30    std::ostringstream s;   
31            
32    guint32 lgth;
33    char greltag[10];  //group element tag
34  
35    s << "------------ using listEntries ----------------" << std::endl; 
36
37    char st[20];
38    for (ListTag::iterator i = listEntries.begin();  
39            i != listEntries.end();
40            ++i){
41         (*i)->SetPrintLevel(printLevel);
42         (*i)->Print(os);   
43    } 
44    os<<s.str();
45
46
47 //-----------------------------------------------------------------------------
48 // Public
49 /**
50  * \ingroup gdcmHeader
51  * \brief  add a new Dicom Element pointer to 
52  *         the H Table and to the chained List
53  * \warning  push_bash in listEntries ONLY during ParseHeader
54  * \todo  something to allow further Elements addition,
55  * \      when position to be taken care of     
56  * @param   newHeaderEntry
57  */
58 /*void gdcmHeader::Add(gdcmHeaderEntry * newHeaderEntry) {
59
60 // tagHT [newHeaderEntry->GetKey()]  = newHeaderEntry;
61    tagHT.insert( PairHT( newHeaderEntry->GetKey(),newHeaderEntry) );
62    listEntries.push_back(newHeaderEntry); 
63    wasUpdated = 1;
64 }
65
66
67 /**
68  * \ingroup gdcmHeader
69  * \brief   Sets a 'non string' value to a given Dicom Element
70  * @param   area
71  * @param   group Group number of the searched Dicom Element 
72  * @param   element Element number of the searched Dicom Element 
73  * @return  
74  */
75 /*bool gdcmHeader::SetVoidAreaByNumber(void * area,
76                                       guint16 group, guint16 element) {
77    TagKey key = gdcmDictEntry::TranslateToKey(group, element);
78    if ( ! tagHT.count(key))
79       return false;
80    //tagHT[key]->SetVoidArea(area);
81    ( ((tagHT.equal_range(key)).first)->second )->SetVoidArea(area);      
82    return true ;                
83 }
84
85 /**
86  * \ingroup gdcmHeader
87  * \brief   Generate a free TagKey i.e. a TagKey that is not present
88  *          in the TagHt dictionary.
89  * @param   group The generated tag must belong to this group.  
90  * @return  The element of tag with given group which is fee.
91  */
92 /*guint32 gdcmHeader::GenerateFreeTagKeyInGroup(guint16 group) {
93    for (guint32 elem = 0; elem < UINT32_MAX; elem++) {
94       TagKey key = gdcmDictEntry::TranslateToKey(group, elem);
95       if (tagHT.count(key) == 0)
96          return elem;
97    }
98    return UINT32_MAX;
99 }
100
101 //-----------------------------------------------------------------------------
102 // Protected
103
104 //-----------------------------------------------------------------------------
105 // Private
106 /**
107  * \ingroup gdcmHeader
108  * \brief   Re-computes the length of a ACR-NEMA/Dicom group from a DcmHeader
109  * \warning : to be re-written using the chained list instead of the H table.
110  * \warning : DO NOT use (doesn't work any longer because of the multimap)
111  * \todo : to be re-written using the chained list instead of the H table
112  * @param   SkipSequence TRUE if we don't want to write Sequences (ACR-NEMA Files)
113  * @param   type Type of the File (ExplicitVR,ImplicitVR, ACR, ...) 
114  */
115 /*void gdcmHeader::UpdateGroupLength(bool SkipSequence, FileType type) {
116    guint16 gr, el;
117    std::string vr;
118    
119    gdcmHeaderEntry *elem;
120    char trash[10];
121    std::string str_trash;
122    
123    GroupKey key;
124    GroupHT groupHt;  // to hold the length of each group
125    TagKey tk;
126    // remember :
127    // typedef std::map<GroupKey, int> GroupHT;
128    
129    gdcmHeaderEntry *elemZ;
130   
131    // for each Tag in the DCM Header
132    
133    for (TagHeaderEntryHT::iterator tag2 = tagHT.begin(); 
134         tag2 != tagHT.end();
135         ++tag2){
136
137       elem  = tag2->second;
138       gr = elem->GetGroup();
139       el = elem->GetElement();
140       vr = elem->GetVR(); 
141                  
142       sprintf(trash, "%04x", gr);
143       key = trash;              // generate 'group tag'
144       
145       // if the caller decided not to take SEQUENCEs into account 
146       // e.g : he wants to write an ACR-NEMA File 
147                 
148       if (SkipSequence && vr == "SQ") continue;
149       
150          // Still unsolved problem :
151          // we cannot find the 'Sequence Delimitation Item'
152          // since it's at the end of the Hash Table
153          // (fffe,e0dd) 
154              
155          // pas SEQUENCE en ACR-NEMA
156          // WARNING : 
157          // --> la descente a l'interieur' des SQ 
158          // devrait etre faite avec une liste chainee, pas avec une HTable...
159             
160       if ( groupHt.count(key) == 0) { // we just read the first elem of a given group
161          if (el == 0x0000) {          // the first elem is 0x0000
162             groupHt[key] = 0;         // initialize group length 
163          } else {
164             groupHt[key] = 2 + 2 + 4 + elem->GetLength(); // non 0x0000 first group elem
165          } 
166       } else {   // any elem but the first    
167          if (type == ExplicitVR) {
168             if ( (vr == "OB") || (vr == "OW") || (vr == "SQ") ) {
169                groupHt[key] +=  4; // explicit VR AND OB, OW, SQ : 4 more bytes
170             }
171          }
172          groupHt[key] += 2 + 2 + 4 + elem->GetLength(); 
173       } 
174    }
175
176    unsigned short int gr_bid;
177   
178    for (GroupHT::iterator g = groupHt.begin(); // for each group we found
179         g != groupHt.end();
180         ++g){ 
181       // FIXME: g++ -Wall -Wstrict-prototypes reports on following line:
182       //        warning: unsigned int format, different type arg
183       sscanf(g->first.c_str(),"%x",&gr_bid);
184       tk = g->first + "|0000";                  // generate the element full tag
185                      
186       if ( tagHT.count(tk) == 0) {              // if element 0x0000 not found
187          gdcmDictEntry * tagZ = new gdcmDictEntry(gr_bid, 0x0000, "UL");       
188          elemZ = new gdcmHeaderEntry(tagZ);
189          elemZ->SetLength(4);
190          Add(elemZ);                            // create it
191       } else {
192          elemZ=GetHeaderEntryByNumber(gr_bid, 0x0000);
193       }     
194       sprintf(trash ,"%d",g->second);
195       str_trash=trash;
196       elemZ->SetValue(str_trash);
197    }   
198 }
199
200 /**
201  * \ingroup gdcmHeader
202  * \brief   writes on disc according to the requested format
203  * \        (ACR-NEMA, ExplicitVR, ImplicitVR) the image
204  * \ warning does NOT add the missing elements in the header :
205  * \         it's up to the user doing it !
206  * \         (function CheckHeaderCoherence to be written)
207  * @param   type type of the File to be written 
208  *          (ACR-NEMA, ExplicitVR, ImplicitVR)
209  * @param   _fp already open file pointer
210  */
211 /*void gdcmHeader::WriteEntries(FileType type, FILE * _fp) {
212    guint16 gr, el;
213    guint32 lgr;
214    const char * val;
215    std::string vr;
216    guint32 val_uint32;
217    guint16 val_uint16;
218    
219    std::vector<std::string> tokens;
220    
221    //  uses now listEntries to iterate, not TagHt!
222    //
223    //        pb : gdcmHeader.Add does NOT update listEntries
224    //       TODO : find a trick (in STL?) to do it, at low cost !
225
226    void *ptr;
227
228    // TODO (?) tester les echecs en ecriture (apres chaque fwrite)
229
230    for (ListTag::iterator tag2=listEntries.begin();
231         tag2 != listEntries.end();
232         ++tag2){
233
234       gr =  (*tag2)->GetGroup();
235       el =  (*tag2)->GetElement();
236       lgr = (*tag2)->GetLength();
237       val = (*tag2)->GetValue().c_str();
238       vr =  (*tag2)->GetVR();
239       
240       if ( type == ACR ) { 
241          if (gr < 0x0008)   continue; // ignore pure DICOM V3 groups
242          if (gr %2)         continue; // ignore shadow groups
243          if (vr == "SQ" )   continue; // ignore Sequences
244                    // TODO : find a trick to *skip* the SeQuences !
245                    // Not only ignore the SQ element
246          if (gr == 0xfffe ) continue; // ignore delimiters
247       } 
248
249       fwrite ( &gr,(size_t)2 ,(size_t)1 ,_fp);  //group
250       fwrite ( &el,(size_t)2 ,(size_t)1 ,_fp);  //element
251
252       if ( (type == ExplicitVR) && (gr <= 0x0002) ) {
253          // EXPLICIT VR
254          guint16 z=0, shortLgr;
255          fwrite (vr.c_str(),(size_t)2 ,(size_t)1 ,_fp);
256
257          if ( (vr == "OB") || (vr == "OW") || (vr == "SQ") ) {
258             fwrite ( &z,  (size_t)2 ,(size_t)1 ,_fp);
259             fwrite ( &lgr,(size_t)4 ,(size_t)1 ,_fp);
260
261          } else {
262             shortLgr=lgr;
263             fwrite ( &shortLgr,(size_t)2 ,(size_t)1 ,_fp);
264          }
265       } else { // IMPLICIT VR
266          fwrite ( &lgr,(size_t)4 ,(size_t)1 ,_fp);
267       }
268
269       if (vr == "US" || vr == "SS") {
270          tokens.erase(tokens.begin(),tokens.end()); // clean any previous value
271          Tokenize ((*tag2)->GetValue(), tokens, "\\");
272          for (unsigned int i=0; i<tokens.size();i++) {
273             val_uint16 = atoi(tokens[i].c_str());
274             ptr = &val_uint16;
275             fwrite ( ptr,(size_t)2 ,(size_t)1 ,_fp);
276          }
277          tokens.clear();
278          continue;
279       }
280       if (vr == "UL" || vr == "SL") {
281          tokens.erase(tokens.begin(),tokens.end()); // clean any previous value
282          Tokenize ((*tag2)->GetValue(), tokens, "\\");
283          for (unsigned int i=0; i<tokens.size();i++) {
284             val_uint32 = atoi(tokens[i].c_str());
285             ptr = &val_uint32;
286             fwrite ( ptr,(size_t)4 ,(size_t)1 ,_fp);
287          }
288          tokens.clear();
289          continue;
290       }     
291       // Pixels are never loaded in the element !
292       if ((gr == 0x7fe0) && (el == 0x0010) ) break;
293
294       fwrite ( val,(size_t)lgr ,(size_t)1 ,_fp); // Elem value
295    }
296 }
297 */
298 //-----------------------------------------------------------------------------