]> Creatis software - gdcm.git/blob - src/gdcmObject.cxx
update CMakeLists
[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() != 0xe000);
100           --i,j--) {   
101       }
102       beginObj=j;
103    }
104          
105   // upwards again to fffe,e000   
106    if (fin()== (--(plistEntries->end())) )  // Don't try anything more when end 
107        return;                              // of Chained List is reached   
108                                            
109    for( i=j=fin();
110         ((*i)->GetGroup() != 0xfffe)  && ((*i)->GetElement() != 0xe000);
111         --i,j--) {          
112    }
113    j--;
114    endObj=j;    
115 }
116
117 /**
118  * \ingroup gdcmParser
119  * \brief   Sets Entry (Dicom Element) value of an element,
120  *          specified by it's tag (Group, Number) 
121  *          and the length, too ...
122  *          If the Element is not found, it's just created !
123  * \warning we suppose, right now, the element belongs to a Public Group
124  *          (NOT a shadow one)       
125  * @param   val string value to set
126  * @param   group Group of the searched tag.
127  * @param   element Element of the searched tag.
128  * @return  true if element was found or created successfully
129  */
130  bool gdcmObject::SetEntryByNumber(std::string val,guint16 group, 
131                                                    guint16 element) {
132
133    for(ListTag::iterator i=beginObj;;++i) { 
134       if ( (*i)->GetGroup() == 0xfffe && (*i)->GetElement() == 0xe000 ) 
135          continue;
136       if ( group   < (*i)->GetGroup() || 
137            (group == (*i)->GetGroup() && element < (*i)->GetElement()) ){
138          // instead of ReplaceOrCreateByNumber 
139          // that is a method of gdcmParser :-( 
140          gdcmHeaderEntry *Entry;
141          TagKey key = gdcmDictEntry::TranslateToKey(group, element);
142          if ( ! ptagHT->count(key)) {
143            // we assume a Public Dictionnary *is* loaded
144            gdcmDict *PubDict         = gdcmGlobal::GetDicts()->GetDefaultPubDict();
145            // if the invoked (group,elem) doesn't exist inside the Dictionary
146            // we create a VirtualDictEntry
147            gdcmDictEntry *DictEntry  = PubDict->GetDictEntryByNumber(group, element);
148            if (DictEntry == NULL) {
149               DictEntry=gdcmGlobal::GetDicts()->NewVirtualDictEntry(group,element,"UN","??","??");
150            } 
151            // we assume the constructor didn't fail
152            Entry = new gdcmHeaderEntry(DictEntry);
153            // ----
154            // TODO
155            // ----
156            // better we don't assume too much !
157            // in the next release, gdcmObject will be used 
158            // to describe any Header Entry ...
159          } else {
160             Entry = ptagHT->find(key)->second;
161          }
162          Entry->SetValue(val); 
163          Entry->SetLength(val.length());
164          plistEntries->insert(i,Entry); 
165          return true;
166       }    
167       if (group == (*i)->GetGroup() && element == (*i)->GetElement() ) {
168          (*i)->SetValue(val);
169          (*i)->SetLength(val.length()); 
170          return true;    
171       }   
172    }                                                
173 }
174 /**
175  * \ingroup gdcmObject
176  * \brief   Builds a hash table (multimap) containing 
177  *          pointers to all Header Entries (i.e Dicom Element)
178  *          related to this 'object'
179  * @return
180  */ 
181 TagHeaderEntryHT gdcmObject::GetEntry(void) {
182    TagHeaderEntryHT HT;
183    for(ListTag::iterator i=beginObj;;++i) {
184       HT.insert( PairHT( (*i)->GetKey(),(*i)) );
185       if (i == endObj) break;      
186    }
187    return(HT);
188 }
189
190 /**
191  * \ingroup gdcmObject
192  * \brief   Builds a Chained List containing 
193  *          pointers to all Header Entries (i.e Dicom Element)
194  *          related to this 'object'
195  * @return
196  */ 
197 ListTag gdcmObject::GetListEntry(void) {
198    ListTag list;
199    for(ListTag::iterator i=beginObj;;++i) {
200       list.push_back(*i);
201       if (i == endObj) break;      
202    }
203    return(list);
204 }
205
206
207 //-----------------------------------------------------------------------------
208 // Protected
209 /**
210  * \ingroup gdcmObject
211  * \brief   add the 'Object' related Dicom Elements to the listEntries
212  *          of a partially created DICOMDIR
213  */
214 void gdcmObject::FillObject(std::list<gdcmElement> elemList) {
215    std::list<gdcmElement>::iterator it;
216    guint16 tmpGr,tmpEl;
217    gdcmDictEntry *dictEntry;
218    gdcmHeaderEntry *entry;
219       
220    debInsertion = this->fin(); 
221    ++debInsertion;
222    finInsertion=debInsertion;
223    
224    for(it=elemList.begin();it!=elemList.end();++it)
225    {
226       tmpGr=it->group;
227       tmpEl=it->elem;
228       dictEntry=gdcmGlobal::GetDicts()->GetDefaultPubDict()->GetDictEntryByNumber(tmpGr,tmpEl);
229       entry=new gdcmHeaderEntry(dictEntry);
230       entry->SetOffset(0); // just to avoid further missprinting
231       entry->SetValue(it->value);
232
233       if(dictEntry->GetGroup()==0xfffe) 
234          {
235             entry->SetLength(entry->GetValue().length());        
236          }
237       else if( (dictEntry->GetVR()=="UL") || (dictEntry->GetVR()=="SL") ) 
238          {
239             entry->SetLength(4);
240          } 
241       else if( (dictEntry->GetVR()=="US") || (dictEntry->GetVR()=="SS") ) 
242          {
243             entry->SetLength(2); 
244          } 
245       else if(dictEntry->GetVR()=="SQ") 
246          {
247             entry->SetLength(0xffffffff);
248          }
249       else
250          {
251             entry->SetLength(entry->GetValue().length());        
252          }                                
253       ptagHT->insert( PairHT(entry->GetKey(),entry) ); // add in the (multimap) H Table
254       plistEntries->insert(debInsertion ,entry);       // add at the begining of the Patient list
255       ++finInsertion;                                      
256    }
257      
258    i=fin();
259    i++;
260    j=debInsertion;
261    j--;
262 }   
263 //-----------------------------------------------------------------------------
264 // Private
265
266 //-----------------------------------------------------------------------------