]> Creatis software - gdcm.git/blob - src/gdcmObject.cxx
72b41f234af01fe6104e633e663fe1f39f567c19
[gdcm.git] / src / gdcmObject.cxx
1 // gdcmObject.cxx
2 //-----------------------------------------------------------------------------
3 #include "gdcmObject.h"
4 #include "gdcmGlobal.h"
5 #include "gdcmDebug.h"
6
7 //-----------------------------------------------------------------------------
8 /**
9  * \ingroup gdcmObject
10  * \brief  Constructor 
11  * @param  begin  iterator on the first Header Entry (i.e Dicom Element)
12  *                related to this 'Object'
13  * @param  end  iterator on the last Header Entry 
14  *              (i.e Dicom Element) related to this 'Object'             
15  * @param ptagHT pointer to the HTable (gdcmObject needs it 
16  *               to build the gdcmHeaderEntries)
17  * @param plistEntries pointer to the chained List (gdcmObject needs it 
18  *               to build the gdcmHeaderEntries)
19  */
20 gdcmObject::gdcmObject(ListTag::iterator begin, ListTag::iterator end,
21               TagHeaderEntryHT *ptagHT, ListTag *plistEntries) {
22    beginObj = begin;
23    endObj   = end;
24    this->ptagHT = ptagHT;
25    this->plistEntries = plistEntries;
26    if(begin==end)
27       dbg.Verbose(0, "gdcmObject::gdcmObject empty list");
28 }
29
30 /**
31  * \ingroup gdcmObject
32  * \brief   Canonical destructor.
33  */
34 gdcmObject::~gdcmObject(void) {
35 }
36
37 //-----------------------------------------------------------------------------
38 // Print
39 /**
40  * \ingroup gdcmObject
41  * \brief   Prints the Object
42  * @return
43  */ 
44 void gdcmObject::Print(std::ostream &os) {
45    if(printLevel>=0) {
46       ListTag::iterator i;
47       for(i=beginObj;;++i) {
48          (*i)->SetPrintLevel(printLevel);
49          (*i)->Print(os);
50          if (i == endObj) break;
51       }
52    }
53 }
54
55 //-----------------------------------------------------------------------------
56 // Public
57 /**
58  * \ingroup gdcmObject
59  * \brief   Get the value of an Header Entries (i.e Dicom Element) by number
60  * @return
61  */ 
62 std::string gdcmObject::GetEntryByNumber(guint16 group, guint16 element) {
63    for(ListTag::iterator i=beginObj;;++i) {
64       if ( (*i)->GetGroup()==group && (*i)->GetElement()==element)
65          return (*i)->GetValue();
66       if (i == endObj) break;  
67    }   
68    return GDCM_UNFOUND;
69 }
70
71 /**
72  * \ingroup gdcmObject
73  * \brief   Get the value of an Header Entries (i.e Dicom Element) by name
74  * @param   name : name of the searched element.
75  * @return
76  */ 
77 std::string gdcmObject::GetEntryByName(TagName name)  {
78    gdcmDict *PubDict=gdcmGlobal::GetDicts()->GetDefaultPubDict();
79    gdcmDictEntry *dictEntry = (*PubDict).GetDictEntryByName(name); 
80
81    if( dictEntry == NULL)
82       return GDCM_UNFOUND;
83    return GetEntryByNumber(dictEntry->GetGroup(),dictEntry->GetElement()); 
84 }
85
86 /**
87  * \ingroup gdcmObject
88  * \brief   Set the 'boundaries' gdcmObject (gdcmDicomDirPatient,
89  *          gdcmDicomDirStudy, gdcmDicomDirSerie, gdcmDicomDirImage)
90  *          comming for the parsing of a DICOMDIR file
91  * \warning NOT en user intended function
92  * @param  flag = 0 when META to be dealt with
93  */ 
94 void gdcmObject::ResetBoundaries(int flag) {
95
96    if (flag) { // it's NOT a META
97      // upwards to fffe,e000   
98        for( i=j=debut();
99             ((*i)->GetGroup() != 0xfffe)  && ((*i)->GetElement() != 0x0000);
100             --i,j--) {      
101        }
102       beginObj=j;
103    }
104          
105   // downwards to fffe,e000       
106    for( i=j=fin();
107         ((*i)->GetGroup() != 0xfffe)  && ((*i)->GetElement() != 0x0000);
108         --i,j--) {          
109    }
110    j--;
111    endObj=j;    
112 }
113
114 /**
115  * \ingroup gdcmParser
116  * \brief   Sets Entry (Dicom Element) value of an element,
117  *          specified by it's tag (Group, Number) 
118  *          and the length, too ...
119  *          If the Element is not found, it's just created !
120  * \warning we suppose, right now, the element belongs to a Public Group
121  *          (NOT a shadow one)       
122  * @param   val string value to set
123  * @param   group Group of the searched tag.
124  * @param   element Element of the searched tag.
125  * @return  true if element was found or created successfully
126  */
127  bool gdcmObject::SetEntryByNumber(std::string val,guint16 group, 
128                                                    guint16 element) {
129
130    for(ListTag::iterator i=beginObj;;++i) { 
131       if ( (*i)->GetGroup() == 0xfffe && (*i)->GetElement() == 0xe000 ) 
132          continue;
133       if ( group   < (*i)->GetGroup() || 
134            (group == (*i)->GetGroup() && element < (*i)->GetElement()) ){
135          // instead of ReplaceOrCreateByNumber 
136          // that is a method of gdcmParser :-( 
137          gdcmHeaderEntry *Entry;
138          TagKey key = gdcmDictEntry::TranslateToKey(group, element);
139          if ( ! ptagHT->count(key)) {
140            // we assume a Public Dictionnary *is* loaded
141            gdcmDict *PubDict         = gdcmGlobal::GetDicts()->GetDefaultPubDict();
142            // if the invoked (group,elem) doesn't exist inside the Dictionary
143            // we create a VirtualDictEntry
144            gdcmDictEntry *DictEntry  = PubDict->GetDictEntryByNumber(group, element);
145            if (DictEntry == NULL) {
146               DictEntry=gdcmGlobal::GetDicts()->NewVirtualDictEntry(group,element,"UN","??","??");
147            } 
148            // we assume the constructor didn't fail
149            Entry = new gdcmHeaderEntry(DictEntry);
150            // ----
151            // TODO
152            // ----
153            // better we don't assume too much !
154            // in the next release, gdcmObject will be used 
155            // to describe any Header Entry ...
156          } else {
157             Entry = ptagHT->find(key)->second;
158          }
159          Entry->SetValue(val); 
160          Entry->SetLength(val.length());
161          plistEntries->insert(i,Entry); 
162          return true;
163       }    
164       if (group == (*i)->GetGroup() && element == (*i)->GetElement() ) {
165          (*i)->SetValue(val);
166          (*i)->SetLength(val.length()); 
167          return true;    
168       }   
169    }                                                
170 }
171 /**
172  * \ingroup gdcmObject
173  * \brief   Builds a hash table (multimap) containing 
174  *          pointers to all Header Entries (i.e Dicom Element)
175  *          related to this 'object'
176  * @return
177  */ 
178 TagHeaderEntryHT gdcmObject::GetEntry(void) {
179    TagHeaderEntryHT HT;
180    for(ListTag::iterator i=beginObj;;++i) {
181       HT.insert( PairHT( (*i)->GetKey(),(*i)) );
182       if (i == endObj) break;      
183    }
184    return(HT);
185 }
186
187 /**
188  * \ingroup gdcmObject
189  * \brief   Builds a Chained List containing 
190  *          pointers to all Header Entries (i.e Dicom Element)
191  *          related to this 'object'
192  * @return
193  */ 
194 ListTag gdcmObject::GetListEntry(void) {
195    ListTag list;
196    for(ListTag::iterator i=beginObj;;++i) {
197       list.push_back(*i);
198       if (i == endObj) break;      
199    }
200    return(list);
201 }
202
203
204 //-----------------------------------------------------------------------------
205 // Protected
206 /**
207  * \ingroup gdcmObject
208  * \brief   add the 'Object' related Dicom Elements to the listEntries
209  *          of a partially created DICOMDIR
210  */
211 void gdcmObject::FillObject(std::list<gdcmElement> elemList) {
212    std::list<gdcmElement>::iterator it;
213    guint16 tmpGr,tmpEl;
214    gdcmDictEntry *dictEntry;
215    gdcmHeaderEntry *entry;
216       
217    debInsertion = this->fin(); 
218    ++debInsertion;
219    finInsertion=debInsertion;
220    
221    for(it=elemList.begin();it!=elemList.end();++it)
222    {
223       tmpGr=it->group;
224       tmpEl=it->elem;
225       dictEntry=gdcmGlobal::GetDicts()->GetDefaultPubDict()->GetDictEntryByNumber(tmpGr,tmpEl);
226       entry=new gdcmHeaderEntry(dictEntry);
227       entry->SetOffset(0); // just to avoid further missprinting
228       entry->SetValue(it->value);
229
230       if(dictEntry->GetGroup()==0xfffe) 
231          {
232             entry->SetLength(entry->GetValue().length());        
233          }
234       else if( (dictEntry->GetVR()=="UL") || (dictEntry->GetVR()=="SL") ) 
235          {
236             entry->SetLength(4);
237          } 
238       else if( (dictEntry->GetVR()=="US") || (dictEntry->GetVR()=="SS") ) 
239          {
240             entry->SetLength(2); 
241          } 
242       else if(dictEntry->GetVR()=="SQ") 
243          {
244             entry->SetLength(0xffffffff);
245          }
246       else
247          {
248             entry->SetLength(entry->GetValue().length());        
249          }                                
250       ptagHT->insert( PairHT(entry->GetKey(),entry) ); // add in the (multimap) H Table
251       plistEntries->insert(debInsertion ,entry);       // add at the begining of the Patient list
252       ++finInsertion;                                      
253    }
254      
255    i=fin();
256    i++;
257    j=debInsertion;
258    j--;
259 }   
260 //-----------------------------------------------------------------------------
261 // Private
262
263 //-----------------------------------------------------------------------------