]> Creatis software - gdcm.git/blob - src/gdcmDict.cxx
Removal out of the Dicom Dictionary of non dicom 'fourth' field
[gdcm.git] / src / gdcmDict.cxx
1 /*=========================================================================
2                                                                                 
3   Program:   gdcm
4   Module:    $RCSfile: gdcmDict.cxx,v $
5   Language:  C++
6   Date:      $Date: 2005/01/07 12:29:17 $
7   Version:   $Revision: 1.56 $
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       dbg.Verbose(2,"Dict::Dict: 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    }
69    from.close();
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    PrintByKey(os);
93 }
94
95 /**
96  * \brief   Print all the dictionary entries contained in this dictionary.
97  *          Entries will be sorted by tag i.e. the couple (group, element).
98  * @param   os The output stream to be written to.
99  */
100 void Dict::PrintByKey(std::ostream &os)
101 {
102    std::ostringstream s;
103
104    for (TagKeyHT::iterator tag = KeyHt.begin(); tag != KeyHt.end(); ++tag)
105    {
106       s << "Entry : ";
107       s << "(" << std::hex << std::setw(4) << tag->second.GetGroup() << ',';
108       s << std::hex << std::setw(4) << tag->second.GetElement() << ") = "
109         << std::dec;
110       s << tag->second.GetVR() << ", ";
111       s << tag->second.GetVM() << ", ";
112       s << tag->second.GetName() << "."  << std::endl;
113    }
114    os << s.str();
115 }
116
117 //-----------------------------------------------------------------------------
118 // Public
119 /**
120  * \ingroup Dict
121  * \brief  adds a new Dicom Dictionary Entry 
122  * @param   newEntry entry to add 
123  * @return  false if Dicom Element already exists
124  */
125 bool Dict::AddNewEntry(DictEntry const &newEntry) 
126 {
127    const TagKey &key = newEntry.GetKey();
128
129    if(KeyHt.count(key) == 1)
130    {
131       dbg.Verbose(1, "Dict::AddNewEntry already present", key.c_str());
132       return false;
133    } 
134    else 
135    {
136       KeyHt.insert( TagKeyHT::value_type(newEntry.GetKey(), newEntry));
137       return true;
138    }
139 }
140
141 /**
142  * \ingroup Dict
143  * \brief  replaces an already existing Dicom Element by a new one
144  * @param   newEntry new entry (overwrites any previous one with same tag)
145  * @return  false if Dicom Element doesn't exist
146  */
147 bool Dict::ReplaceEntry(DictEntry const &newEntry)
148 {
149    if ( RemoveEntry(newEntry.GetKey()) )
150    {
151        KeyHt.insert( TagKeyHT::value_type(newEntry.GetKey(), newEntry));
152        return true;
153    } 
154    return false;
155 }
156
157 /**
158  * \ingroup Dict
159  * \brief  removes an already existing Dicom Dictionary Entry,
160  *         identified by its Tag
161  * @param   key (group|element)
162  * @return  false if Dicom Dictionary Entry doesn't exist
163  */
164 bool Dict::RemoveEntry (TagKey const &key) 
165 {
166    TagKeyHT::const_iterator it = KeyHt.find(key);
167    if(it != KeyHt.end()) 
168    {
169       const DictEntry& entryToDelete = it->second;
170       KeyHt.erase(key);
171
172       return true;
173    } 
174    else 
175    {
176       dbg.Verbose(1, "Dict::RemoveEntry unfound entry", key.c_str());
177       return false;
178   }
179 }
180
181 /**
182  * \brief  removes an already existing Dicom Dictionary Entry, 
183  *          identified by its group,element number
184  * @param   group   Dicom group number of the Dicom Element
185  * @param   elem Dicom element number of the Dicom Element
186  * @return  false if Dicom Dictionary Entry doesn't exist
187  */
188 bool Dict::RemoveEntry (uint16_t group, uint16_t elem)
189 {
190    return RemoveEntry(DictEntry::TranslateToKey(group, elem));
191 }
192
193 /**
194  * \brief   Get the dictionnary entry identified by a given tag (group,element)
195  * @param   group   group of the entry to be found
196  * @param   elem element of the entry to be found
197  * @return  the corresponding dictionnary entry when existing, NULL otherwise
198  */
199 DictEntry *Dict::GetDictEntryByNumber(uint16_t group, uint16_t elem)
200 {
201    TagKey key = DictEntry::TranslateToKey(group, elem);
202    TagKeyHT::iterator it = KeyHt.find(key);
203    if ( it == KeyHt.end() )
204    {
205       return 0;
206    }
207    return &(it->second);
208 }
209
210 /** 
211  * \brief   Consider all the entries of the public dicom dictionnary. 
212  *          Build all list of all the tag names of all those entries.
213  * \sa      DictSet::GetPubDictTagNamesByCategory
214  * @return  A list of all entries of the public dicom dictionnary.
215  */
216
217  
218  // Probabely useless
219   
220  
221 //EntryNamesList *Dict::GetDictEntryNames() 
222 //{
223 //   EntryNamesList *result = new EntryNamesList;
224 //   for (TagKeyHT::iterator tag = KeyHt.begin(); tag != KeyHt.end(); ++tag)
225 //   {
226 //      result->push_back( tag->second.GetName() );
227 //   }
228 //   return result;
229 //}
230
231 /** 
232  * \ingroup Dict
233  * \brief   Consider all the entries of the public dicom dictionnary.
234  *          Build an hashtable whose keys are the names of the groups
235  *          (fourth field in each line of dictionary) and whose corresponding
236  *          values are lists of all the dictionnary entries among that
237  *          group. Note that apparently the Dicom standard doesn't explicitely
238  *          define a name (as a string) for each group.
239  *          A typical usage of this method would be to enable a dynamic
240  *          configuration of a Dicom file browser: the admin/user can
241  *          select in the interface which Dicom tags should be displayed.
242  * \warning Dicom *doesn't* define any name for any 'categorie'
243  *          (the dictionnary fourth field was formerly NIH defined
244  *           - and no longer he is-
245  *           and will be removed when Dicom provides us a text file
246  *           with the 'official' Dictionnary, that would be more friendly
247  *           than asking us to perform a line by line check of the dictionnary
248  *           at the beginning of each year to -try to- guess the changes)
249  *           Therefore : please NEVER use that fourth field :-(
250  *
251  * @return  An hashtable: whose keys are the names of the groups and whose
252  *          corresponding values are lists of all the dictionnary entries
253  *          among that group.
254  */
255  
256  // Probabely useless
257  
258 //EntryNamesByCatMap *Dict::GetDictEntryNamesByCategory() 
259 //{
260 //   EntryNamesByCatMap *result = new EntryNamesByCatMap;
261 //
262 //   for (TagKeyHT::iterator tag = KeyHt.begin(); tag != KeyHt.end(); ++tag)
263 //   {
264 //      (*result)[tag->second.GetFourth()].push_back(tag->second.GetName());
265 //   }
266 //
267 //   return result;
268 //}
269
270 //-----------------------------------------------------------------------------
271 // Protected
272
273 //-----------------------------------------------------------------------------
274 // Private
275
276 //-----------------------------------------------------------------------------
277
278 } // end namespace gdcm