]> Creatis software - gdcm.git/blob - src/gdcmDict.cxx
* Bug fix for the python part use
[gdcm.git] / src / gdcmDict.cxx
1 /*=========================================================================
2                                                                                 
3   Program:   gdcm
4   Module:    $RCSfile: gdcmDict.cxx,v $
5   Language:  C++
6   Date:      $Date: 2005/01/12 15:23:44 $
7   Version:   $Revision: 1.62 $
8                                                                                 
9   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
10   l'Image). All rights reserved. See Doc/License.txt or
11   http://www.creatis.insa-lyon.fr/Public/Gdcm/License.html for details.
12                                                                                 
13      This software is distributed WITHOUT ANY WARRANTY; without even
14      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15      PURPOSE.  See the above copyright notices for more information.
16                                                                                 
17 =========================================================================*/
18
19 #include "gdcmDict.h"
20 #include "gdcmUtil.h"
21 #include "gdcmDebug.h"
22
23 #include <fstream>
24 #include <iostream>
25 #include <iomanip>
26
27 namespace gdcm 
28 {
29 void FillDefaultDataDict(Dict *d);
30 //-----------------------------------------------------------------------------
31 // Constructor / Destructor
32 /**
33  * \brief   Constructor
34  * @param   filename from which to build the dictionary.
35  */
36 Dict::Dict(std::string const &filename)
37 {
38    uint16_t group;
39    uint16_t element;
40    TagName vr;
41    TagName vm;
42    TagName name;
43
44    std::ifstream from( filename.c_str() );
45    if( !from )
46    {
47       gdcmVerboseMacro( "Can't open dictionary" << filename.c_str());
48       // Using default embeded one:
49       FillDefaultDataDict( this );
50    }
51    else
52    {
53       while (!from.eof())
54       {
55          from >> std::hex;
56          from >> group;
57          from >> element;
58          from >> vr;
59          from >> vm;
60          from >> std::ws;  //remove white space
61          std::getline(from, name);
62    
63          const DictEntry newEntry(group, element, vr, vm, name);
64          AddNewEntry(newEntry);
65       }
66
67       Filename = filename;
68       from.close();
69    }
70 }
71
72 /**
73  * \brief  Destructor 
74  */
75 Dict::~Dict()
76 {
77    // we assume all the pointed DictEntries are already cleaned-up
78    // when we clean KeyHt.
79    KeyHt.clear();
80 }
81
82 //-----------------------------------------------------------------------------
83 // Print
84 /**
85  * \brief   Print all the dictionary entries contained in this dictionary.
86  *          Entries will be sorted by tag i.e. the couple (group, element).
87  * @param   os The output stream to be written to.
88  */
89 void Dict::Print(std::ostream &os)
90 {
91    os << "Dict file name : " << Filename << std::endl;
92    std::ostringstream s;
93
94    for (TagKeyHT::iterator tag = KeyHt.begin(); tag != KeyHt.end(); ++tag)
95    {
96       s << "Entry : ";
97       s << "(" << std::hex << std::setw(4) << tag->second.GetGroup() << ',';
98       s << std::hex << std::setw(4) << tag->second.GetElement() << ") = "
99         << std::dec;
100       s << tag->second.GetVR() << ", ";
101       s << tag->second.GetVM() << ", ";
102       s << tag->second.GetName() << "."  << std::endl;
103    }
104    os << s.str();
105 }
106
107
108 //-----------------------------------------------------------------------------
109 // Public
110 /**
111  * \ingroup Dict
112  * \brief  adds a new Dicom Dictionary Entry 
113  * @param   newEntry entry to add 
114  * @return  false if Dicom Element already exists
115  */
116 bool Dict::AddNewEntry(DictEntry const &newEntry) 
117 {
118    const TagKey &key = newEntry.GetKey();
119
120    if(KeyHt.count(key) == 1)
121    {
122       gdcmVerboseMacro( "Already present" << key.c_str());
123       return false;
124    } 
125    else 
126    {
127       KeyHt.insert( TagKeyHT::value_type(newEntry.GetKey(), newEntry));
128       return true;
129    }
130 }
131
132 /**
133  * \ingroup Dict
134  * \brief  replaces an already existing Dicom Element by a new one
135  * @param   newEntry new entry (overwrites any previous one with same tag)
136  * @return  false if Dicom Element doesn't exist
137  */
138 bool Dict::ReplaceEntry(DictEntry const &newEntry)
139 {
140    if ( RemoveEntry(newEntry.GetKey()) )
141    {
142        KeyHt.insert( TagKeyHT::value_type(newEntry.GetKey(), newEntry));
143        return true;
144    } 
145    return false;
146 }
147
148 /**
149  * \ingroup Dict
150  * \brief  removes an already existing Dicom Dictionary Entry,
151  *         identified by its Tag
152  * @param   key (group|element)
153  * @return  false if Dicom Dictionary Entry doesn't exist
154  */
155 bool Dict::RemoveEntry (TagKey const &key) 
156 {
157    TagKeyHT::const_iterator it = KeyHt.find(key);
158    if(it != KeyHt.end()) 
159    {
160       KeyHt.erase(key);
161
162       return true;
163    } 
164    else 
165    {
166       gdcmVerboseMacro( "Unfound entry" << key.c_str());
167       return false;
168   }
169 }
170
171 /**
172  * \brief  removes an already existing Dicom Dictionary Entry, 
173  *          identified by its group,element number
174  * @param   group   Dicom group number of the Dicom Element
175  * @param   elem Dicom element number of the Dicom Element
176  * @return  false if Dicom Dictionary Entry doesn't exist
177  */
178 bool Dict::RemoveEntry (uint16_t group, uint16_t elem)
179 {
180    return RemoveEntry(DictEntry::TranslateToKey(group, elem));
181 }
182
183 /**
184  * \brief   Get the dictionnary entry identified by a given tag (group,element)
185  * @param   group   group of the entry to be found
186  * @param   elem element of the entry to be found
187  * @return  the corresponding dictionnary entry when existing, NULL otherwise
188  */
189 DictEntry *Dict::GetDictEntry(uint16_t group, uint16_t elem)
190 {
191    TagKey key = DictEntry::TranslateToKey(group, elem);
192    TagKeyHT::iterator it = KeyHt.find(key);
193    if ( it == KeyHt.end() )
194    {
195       return 0;
196    }
197    return &(it->second);
198 }
199
200 /** 
201  * \brief   Consider all the entries of the public dicom dictionnary. 
202  *          Build all list of all the tag names of all those entries.
203  * \sa      DictSet::GetPubDictTagNamesByCategory
204  * @return  A list of all entries of the public dicom dictionnary.
205  */
206
207  
208  // Probabely useless
209   
210  
211 //EntryNamesList *Dict::GetDictEntryNames() 
212 //{
213 //   EntryNamesList *result = new EntryNamesList;
214 //   for (TagKeyHT::iterator tag = KeyHt.begin(); tag != KeyHt.end(); ++tag)
215 //   {
216 //      result->push_back( tag->second.GetName() );
217 //   }
218 //   return result;
219 //}
220
221 /** 
222  * \ingroup Dict
223  * \brief   Consider all the entries of the public dicom dictionnary.
224  *          Build an hashtable whose keys are the names of the groups
225  *          (fourth field in each line of dictionary) and whose corresponding
226  *          values are lists of all the dictionnary entries among that
227  *          group. Note that apparently the Dicom standard doesn't explicitely
228  *          define a name (as a string) for each group.
229  *          A typical usage of this method would be to enable a dynamic
230  *          configuration of a Dicom file browser: the admin/user can
231  *          select in the interface which Dicom tags should be displayed.
232  * \warning Dicom *doesn't* define any name for any 'categorie'
233  *          (the dictionnary fourth field was formerly NIH defined
234  *           - and no longer he is-
235  *           and will be removed when Dicom provides us a text file
236  *           with the 'official' Dictionnary, that would be more friendly
237  *           than asking us to perform a line by line check of the dictionnary
238  *           at the beginning of each year to -try to- guess the changes)
239  *           Therefore : please NEVER use that fourth field :-(
240  *
241  * @return  An hashtable: whose keys are the names of the groups and whose
242  *          corresponding values are lists of all the dictionnary entries
243  *          among that group.
244  */
245  
246  // Probabely useless
247  
248 //EntryNamesByCatMap *Dict::GetDictEntryNamesByCategory() 
249 //{
250 //   EntryNamesByCatMap *result = new EntryNamesByCatMap;
251 //
252 //   for (TagKeyHT::iterator tag = KeyHt.begin(); tag != KeyHt.end(); ++tag)
253 //   {
254 //      (*result)[tag->second.GetFourth()].push_back(tag->second.GetName());
255 //   }
256 //
257 //   return result;
258 //}
259
260 //-----------------------------------------------------------------------------
261 // Protected
262
263 //-----------------------------------------------------------------------------
264 // Private
265
266 //-----------------------------------------------------------------------------
267
268 } // end namespace gdcm