GDCM
2.0.18
|
00001 /*========================================================================= 00002 00003 Program: GDCM (Grassroots DICOM). A DICOM library 00004 00005 Copyright (c) 2006-2011 Mathieu Malaterre 00006 All rights reserved. 00007 See Copyright.txt or http://gdcm.sourceforge.net/Copyright.html for details. 00008 00009 This software is distributed WITHOUT ANY WARRANTY; without even 00010 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 00011 PURPOSE. See the above copyright notice for more information. 00012 00013 =========================================================================*/ 00014 #ifndef GDCMDICT_H 00015 #define GDCMDICT_H 00016 00017 #include "gdcmTypes.h" 00018 #include "gdcmTag.h" 00019 #include "gdcmPrivateTag.h" 00020 #include "gdcmDictEntry.h" 00021 #include "gdcmSystem.h" 00022 00023 #include <iostream> 00024 #include <iomanip> 00025 #include <map> 00026 00027 /* 00028 * FIXME / TODO 00029 * I need to seriously rewrite this mess. a class template should work for both a public 00030 * and a private dict 00031 */ 00032 00033 namespace gdcm 00034 { 00035 // Data Element Tag 00044 class GDCM_EXPORT Dict 00045 { 00046 public: 00047 typedef std::map<Tag, DictEntry> MapDictEntry; 00048 typedef MapDictEntry::iterator Iterator; 00049 typedef MapDictEntry::const_iterator ConstIterator; 00050 //static DictEntry GroupLengthDictEntry; // = DictEntry("Group Length",VR::UL,VM::VM1); 00051 00052 Dict():DictInternal() { 00053 assert( DictInternal.empty() ); 00054 } 00055 00056 friend std::ostream& operator<<(std::ostream& _os, const Dict &_val); 00057 00058 ConstIterator Begin() const { return DictInternal.begin(); } 00059 ConstIterator End() const { return DictInternal.end(); } 00060 00061 bool IsEmpty() const { return DictInternal.empty(); } 00062 void AddDictEntry(const Tag &tag, const DictEntry &de) 00063 { 00064 #ifndef NDEBUG 00065 MapDictEntry::size_type s = DictInternal.size(); 00066 #endif 00067 DictInternal.insert( 00068 MapDictEntry::value_type(tag, de)); 00069 assert( s < DictInternal.size() ); 00070 } 00071 00072 const DictEntry &GetDictEntry(const Tag &tag) const 00073 { 00074 MapDictEntry::const_iterator it = 00075 DictInternal.find(tag); 00076 if (it == DictInternal.end()) 00077 { 00078 #ifdef UNKNOWNPUBLICTAG 00079 // test.acr 00080 if( tag != Tag(0x28,0x15) 00081 && tag != Tag(0x28,0x16) 00082 && tag != Tag(0x28,0x199) 00083 // gdcmData/TheralysGDCM1.dcm 00084 && tag != Tag(0x20,0x1) 00085 // gdcmData/0019004_Baseline_IMG1.dcm 00086 && tag != Tag(0x8348,0x339) 00087 && tag != Tag(0xb5e8,0x338) 00088 // gdcmData/dicomdir_Acusson_WithPrivate_WithSR 00089 && tag != Tag(0x40,0xa125) 00090 ) 00091 { 00092 assert( 0 && "Impossible" ); 00093 } 00094 #endif 00095 it = DictInternal.find( Tag(0xffff,0xffff) ); 00096 return it->second; 00097 } 00098 assert( DictInternal.count(tag) == 1 ); 00099 return it->second; 00100 } 00101 00103 const char *GetKeywordFromTag(Tag const & tag) const 00104 { 00105 MapDictEntry::const_iterator it = 00106 DictInternal.find(tag); 00107 if (it == DictInternal.end()) 00108 { 00109 return NULL; 00110 } 00111 assert( DictInternal.count(tag) == 1 ); 00112 return it->second.GetKeyword(); 00113 } 00114 00119 const DictEntry &GetDictEntryByKeyword(const char *keyword, Tag & tag) const 00120 { 00121 MapDictEntry::const_iterator it = 00122 DictInternal.begin(); 00123 if( keyword ) 00124 { 00125 for(; it != DictInternal.end(); ++it) 00126 { 00127 if( strcmp( keyword, it->second.GetKeyword() ) == 0 ) 00128 { 00129 // Found a match ! 00130 tag = it->first; 00131 break; 00132 } 00133 } 00134 } 00135 else 00136 { 00137 it = DictInternal.end(); 00138 } 00139 if (it == DictInternal.end()) 00140 { 00141 tag = Tag(0xffff,0xffff); 00142 it = DictInternal.find( tag ); 00143 return it->second; 00144 } 00145 assert( DictInternal.count(tag) == 1 ); 00146 return it->second; 00147 } 00148 00152 const DictEntry &GetDictEntryByName(const char *name, Tag & tag) const 00153 { 00154 MapDictEntry::const_iterator it = 00155 DictInternal.begin(); 00156 if( name ) 00157 { 00158 for(; it != DictInternal.end(); ++it) 00159 { 00160 if( strcmp( name, it->second.GetName() ) == 0 ) 00161 { 00162 // Found a match ! 00163 tag = it->first; 00164 break; 00165 } 00166 } 00167 } 00168 else 00169 { 00170 it = DictInternal.end(); 00171 } 00172 if (it == DictInternal.end()) 00173 { 00174 tag = Tag(0xffff,0xffff); 00175 it = DictInternal.find( tag ); 00176 return it->second; 00177 } 00178 assert( DictInternal.count(tag) == 1 ); 00179 return it->second; 00180 } 00181 00182 protected: 00183 friend class Dicts; 00184 void LoadDefault(); 00185 00186 private: 00187 Dict &operator=(const Dict &_val); // purposely not implemented 00188 Dict(const Dict &_val); // purposely not implemented 00189 00190 MapDictEntry DictInternal; 00191 }; 00192 //----------------------------------------------------------------------------- 00193 inline std::ostream& operator<<(std::ostream& os, const Dict &val) 00194 { 00195 Dict::MapDictEntry::const_iterator it = val.DictInternal.begin(); 00196 for(;it != val.DictInternal.end(); ++it) 00197 { 00198 const Tag &t = it->first; 00199 const DictEntry &de = it->second; 00200 os << t << " " << de << '\n'; 00201 } 00202 00203 return os; 00204 } 00205 00206 // TODO 00207 // For private dict, element < 0x10 should automatically defined: 00208 // Name = "Private Creator" 00209 // ValueRepresentation = LO 00210 // ValueMultiplicity = 1 00211 // Owner = "" 00212 00216 class GDCM_EXPORT PrivateDict 00217 { 00218 typedef std::map<PrivateTag, DictEntry> MapDictEntry; 00219 friend std::ostream& operator<<(std::ostream& os, const PrivateDict &val); 00220 public: 00221 PrivateDict() {} 00222 ~PrivateDict() {} 00223 void AddDictEntry(const PrivateTag &tag, const DictEntry &de) 00224 { 00225 #ifndef NDEBUG 00226 MapDictEntry::size_type s = DictInternal.size(); 00227 #endif 00228 DictInternal.insert( 00229 MapDictEntry::value_type(tag, de)); 00230 // The following code should only be used when manually constructing a Private.xml file by hand 00231 // it will get rid of VR::UN duplicate (ie. if a VR != VR::Un can be found) 00232 #if defined(NDEBUG) && 0 00233 if( s == DictInternal.size() ) 00234 { 00235 MapDictEntry::iterator it = 00236 DictInternal.find(tag); 00237 assert( it != DictInternal.end() ); 00238 DictEntry &duplicate = it->second; 00239 assert( de.GetVR() == VR::UN || duplicate.GetVR() == VR::UN ); 00240 assert( de.GetVR() != duplicate.GetVR() ); 00241 if( duplicate.GetVR() == VR::UN ) 00242 { 00243 assert( de.GetVR() != VR::UN ); 00244 duplicate.SetVR( de.GetVR() ); 00245 duplicate.SetVM( de.GetVM() ); 00246 assert( GetDictEntry(tag).GetVR() != VR::UN ); 00247 assert( GetDictEntry(tag).GetVR() == de.GetVR() ); 00248 assert( GetDictEntry(tag).GetVM() == de.GetVM() ); 00249 } 00250 return; 00251 } 00252 #endif 00253 assert( s < DictInternal.size() /*&& std::cout << tag << "," << de << std::endl*/ ); 00254 } 00257 bool RemoveDictEntry(const PrivateTag &tag) 00258 { 00259 MapDictEntry::size_type s = 00260 DictInternal.erase(tag); 00261 assert( s == 1 || s == 0 ); 00262 return s == 1; 00263 } 00264 const DictEntry &GetDictEntry(const PrivateTag &tag) const 00265 { 00266 // if 0x10 -> return Private Creator 00267 MapDictEntry::const_iterator it = 00268 DictInternal.find(tag); 00269 if (it == DictInternal.end()) 00270 { 00271 //assert( 0 && "Impossible" ); 00272 it = DictInternal.find( PrivateTag(0xffff,0xffff,"GDCM Private Sentinel" ) ); 00273 assert (it != DictInternal.end()); 00274 return it->second; 00275 } 00276 assert( DictInternal.count(tag) == 1 ); 00277 return it->second; 00278 } 00279 00280 00281 void PrintXML() const 00282 { 00283 MapDictEntry::const_iterator it = DictInternal.begin(); 00284 std::cout << "<dict edition=\"2008\">\n"; 00285 for(;it != DictInternal.end(); ++it) 00286 { 00287 const PrivateTag &t = it->first; 00288 const DictEntry &de = it->second; 00289 std::cout << " <entry group=\"" << std::hex << std::setw(4) 00290 << std::setfill('0') << t.GetGroup() << "\"" << 00291 " element=\"xx" << std::setw(2) << std::setfill('0')<< t.GetElement() << "\"" << " vr=\"" 00292 << de.GetVR() << "\" vm=\"" << de.GetVM() << "\" owner=\"" 00293 << t.GetOwner(); 00294 const char *name = de.GetName(); 00295 if( *name == 0 ) 00296 { 00297 std::cout << "\"/>\n"; 00298 } 00299 else 00300 { 00301 std::cout << "\" name=\"" << de.GetName() << "\"/>\n"; 00302 } 00303 } 00304 std::cout << "</dict>\n"; 00305 } 00306 00307 bool IsEmpty() const { return DictInternal.empty(); } 00308 protected: 00309 friend class Dicts; 00310 void LoadDefault(); 00311 00312 private: 00313 PrivateDict &operator=(const PrivateDict &_val); // purposely not implemented 00314 PrivateDict(const PrivateDict &_val); // purposely not implemented 00315 00316 MapDictEntry DictInternal; 00317 }; 00318 //----------------------------------------------------------------------------- 00319 inline std::ostream& operator<<(std::ostream& os, const PrivateDict &val) 00320 { 00321 PrivateDict::MapDictEntry::const_iterator it = val.DictInternal.begin(); 00322 for(;it != val.DictInternal.end(); ++it) 00323 { 00324 const PrivateTag &t = it->first; 00325 const DictEntry &de = it->second; 00326 os << t << " " << de << '\n'; 00327 } 00328 00329 return os; 00330 } 00331 00332 } // end namespace gdcm 00333 00334 #endif //GDCMDICT_H