]> Creatis software - gdcm.git/blob - src/gdcmDocEntrySet.cxx
about compile errors
[gdcm.git] / src / gdcmDocEntrySet.cxx
1 // gdcmDocEntrySet.cxx
2 //-----------------------------------------------------------------------------
3 //
4 #include "gdcmDocEntrySet.h"
5
6 #include <iomanip> // for std::ios::left, ...
7
8
9 //-----------------------------------------------------------------------------
10 // Constructor / Destructor
11 /**
12  * \ingroup gdcmDocEntrySEt
13  * \brief   Constructor from a given gdcmDocEntrySet
14  */
15 gdcmDocEntrySet::gdcmDocEntrySet() {
16
17 }
18
19 //-----------------------------------------------------------------------------
20 // Print
21 /*
22  * \ingroup gdcmDocEntrySet
23  * \brief   canonical Printer
24  */
25
26
27 //-----------------------------------------------------------------------------
28 // Public
29
30
31 //-----------------------------------------------------------------------------
32 // Protected
33
34 //-----------------------------------------------------------------------------
35 // Private
36
37 /**
38  * \brief   Parses an EntrySet (Document header or SQ Item )
39  * \       and load element values (a voir !)
40  * @return  false if file is not ACR-NEMA / PAPYRUS / DICOM 
41  */
42 bool gdcmDocument::LoadDocEntrySet(bool exception_on_error) throw(gdcmFormatError) {
43    (void)exception_on_error;
44    rewind(fp);
45    if (!CheckSwap())
46       return false;
47
48    gdcmDocEntry  *newDocEntry = (gdcmDocEntry *)0;     
49    gdcmValEntry  *newValEntry = (gdcmValEntry *)0; 
50    gdcmBinEntry  *newBinEntry = (gdcmBinEntry *)0; 
51    gdcmSeqEntry  *newSeqEntry = (gdcmSeqEntry *)0;  
52    //gdcmDictEntry *NewTag      = (gdcmDictEntry *)0;
53
54    while (newDocEntry = ReadNextDocEntry())) { 
55    // TODO (?) : liberation du DocEntry ainsi cree, 
56    // apres copie dans un ValEntry, SeqEntry, BinEntry   
57       vr = newDocEntry->getVR();
58          
59       if (vr == "SQ" ) {
60       // --- SeqEntry
61       
62          newSeqEntry = (gdcmSeqEntry *)0;
63          if (!NewSeqEntry) {
64             dbg.Verbose(1, "gdcmDocEntrySet::LoadDocEntrySet",
65                            "failed to allocate gdcmSeqEntry");
66             return false;                                
67          }       
68          newSeqEntry->Copy(newDocEntry);            
69       // TODO
70       // SEQUENCE; appel 'récursif' de ??? pour charger la 'valeur'
71       //           (ensemble d' ITEMs, en fait, 
72       //            chaque ITEM etant chargé avec LoadDocEntrySet)
73             
74          SkipDocEntry(newSeqEntry); // voir ce qu'on fait pour une SeQuence
75          AddDocEntry(newSeqEntry); 
76          
77       } else  if (vr == "AE" || vr == "AS" || vr == "DA" || vr == "PN" || 
78                   vr == "UI" || vr == "TM" ) {
79       // --- ValEntry             
80                   
81          newValEntry = (gdcmValEntry *)0;
82          if (!NewValEntry) {
83             dbg.Verbose(1, "gdcmDocEntrySet::LoadDocEntrySet",
84                            "failed to allocate gdcmValEntry");
85             return false;                                
86          }       
87          newValEntry->Copy(newDocEntry);
88          SkipDocEntry(newValEntry); 
89          AddDocEntry(newValEntry); 
90                                                   
91       } else {
92       // --- BinEntry
93       
94          NewBinEntry = new gdcmBinEntry(DictEntry);     
95          if (!NewValEntry) {
96             dbg.Verbose(1, "gdcmDocEntrySet::LoadDocEntrySet",
97                            "failed to allocate gdcmBinEntry");
98             return false;                                
99          }      
100          newBinEntry->Copy(newDocEntry);
101          SkipDocEntry(newBinEntry); 
102          AddDocEntry(newBinEntry);            
103       }                      
104    }   
105    rewind(fp);
106
107
108    // TODO : il n'y a plus de Chained List qui contient toutes les Entries 
109    //        Le chargement des valeurs devra se faire à la volée  
110    // Be carefull : merging this two loops may cause troubles ...
111    for (ListTag::iterator i = GetListEntry().begin();                           
112         i != GetListEntry().end();                                                
113         ++i)                                                                      
114    {                                                                            
115       LoadDocEntry(*i);                                                      
116    }                                                                            
117    rewind(fp);
118     
119    // --------------------------------------------------------------
120    // Special Patch to allow gdcm to read ACR-LibIDO formated images
121    //
122    // if recognition code tells us we deal with a LibIDO image
123    // we switch lineNumber and columnNumber
124    //
125    std::string RecCode;
126    RecCode = GetEntryByNumber(0x0008, 0x0010); // recognition code
127    if (RecCode == "ACRNEMA_LIBIDO_1.1" ||
128        RecCode == "CANRME_AILIBOD1_1." )  // for brain-damaged softwares
129                                           // with "little-endian strings"
130    {
131          filetype = ACR_LIBIDO; 
132          std::string rows    = GetEntryByNumber(0x0028, 0x0010);
133          std::string columns = GetEntryByNumber(0x0028, 0x0011);
134          SetEntryByNumber(columns, 0x0028, 0x0010);
135          SetEntryByNumber(rows   , 0x0028, 0x0011);
136    }
137    // ----------------- End of Special Patch ----------------   
138    return true;
139 }
140
141
142
143 /**
144  * \brief     Check the correspondance between the VR of the header entry
145  *            and the taken VR. If they are different, the header entry is 
146  *            updated with the new VR.
147  * @param     Entry Header Entry to check
148  * @param     vr    Dicom Value Representation
149  * @return    false if the VR is incorrect of if the VR isn't referenced
150  *            otherwise, it returns true
151 */
152
153 // NE MARCHE PAS EN L'ETAT :
154 // On a besoin de VR pour 'fabriquer', au choix ValEntry, BinEntry, ou SeqEntry.
155 //
156
157 bool gdcmDocEntrySet::CheckEntryVR(gdcmHeaderEntry *Entry, VRKey vr)
158 {
159    char msg[100]; // for sprintf
160    bool RealExplicit = true;
161
162    // Assume we are reading a falsely explicit VR file i.e. we reached
163    // a tag where we expect reading a VR but are in fact we read the
164    // first to bytes of the length. Then we will interogate (through find)
165    // the dicom_vr dictionary with oddities like "\004\0" which crashes
166    // both GCC and VC++ implementations of the STL map. Hence when the
167    // expected VR read happens to be non-ascii characters we consider
168    // we hit falsely explicit VR tag.
169
170    if ( (!isalpha(vr[0])) && (!isalpha(vr[1])) )
171       RealExplicit = false;
172
173    // CLEANME searching the dicom_vr at each occurence is expensive.
174    // PostPone this test in an optional integrity check at the end
175    // of parsing or only in debug mode.
176    if ( RealExplicit && !gdcmGlobal::GetVR()->Count(vr) )
177       RealExplicit= false;
178
179    if ( !RealExplicit ) 
180    {
181       // We thought this was explicit VR, but we end up with an
182       // implicit VR tag. Let's backtrack.   
183       sprintf(msg,"Falsely explicit vr file (%04x,%04x)\n", 
184                    Entry->GetGroup(),Entry->GetElement());
185       dbg.Verbose(1, "gdcmParser::FindVR: ",msg);
186       if (Entry->GetGroup()%2 && Entry->GetElement() == 0x0000) { // Group length is UL !
187          gdcmDictEntry* NewEntry = NewVirtualDictEntry(
188                                    Entry->GetGroup(),Entry->GetElement(),
189                                    "UL","FIXME","Group Length");
190          Entry->SetDictEntry(NewEntry);     
191       }
192       return(false);
193    }
194
195    if ( Entry->IsVRUnknown() ) 
196    {
197       // When not a dictionary entry, we can safely overwrite the VR.
198       if (Entry->GetElement() == 0x0000) { // Group length is UL !
199          Entry->SetVR("UL");
200       } else {
201          Entry->SetVR(vr);
202       }
203    }
204    else if ( Entry->GetVR() != vr ) 
205    {
206       // The VR present in the file and the dictionary disagree. We assume
207       // the file writer knew best and use the VR of the file. Since it would
208       // be unwise to overwrite the VR of a dictionary (since it would
209       // compromise it's next user), we need to clone the actual DictEntry
210       // and change the VR for the read one.
211       gdcmDictEntry* NewEntry = NewVirtualDictEntry(
212                                  Entry->GetGroup(),Entry->GetElement(),
213                                  vr,"FIXME",Entry->GetName());
214       Entry->SetDictEntry(NewEntry);
215    }
216    return(true); 
217 }
218
219
220
221
222 //-----------------------------------------------------------------------------