GDCM
2.2.0
|
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 bool FindDictEntry(const PrivateTag &tag) const 00265 { 00266 MapDictEntry::const_iterator it = 00267 DictInternal.find(tag); 00268 if (it == DictInternal.end()) 00269 { 00270 return false; 00271 } 00272 return true; 00273 } 00274 const DictEntry &GetDictEntry(const PrivateTag &tag) const 00275 { 00276 // if 0x10 -> return Private Creator 00277 MapDictEntry::const_iterator it = 00278 DictInternal.find(tag); 00279 if (it == DictInternal.end()) 00280 { 00281 //assert( 0 && "Impossible" ); 00282 it = DictInternal.find( PrivateTag(0xffff,0xffff,"GDCM Private Sentinel" ) ); 00283 assert (it != DictInternal.end()); 00284 return it->second; 00285 } 00286 assert( DictInternal.count(tag) == 1 ); 00287 return it->second; 00288 } 00289 00290 00291 void PrintXML() const 00292 { 00293 MapDictEntry::const_iterator it = DictInternal.begin(); 00294 std::cout << "<dict edition=\"2008\">\n"; 00295 for(;it != DictInternal.end(); ++it) 00296 { 00297 const PrivateTag &t = it->first; 00298 const DictEntry &de = it->second; 00299 std::cout << " <entry group=\"" << std::hex << std::setw(4) 00300 << std::setfill('0') << t.GetGroup() << "\"" << 00301 " element=\"xx" << std::setw(2) << std::setfill('0')<< t.GetElement() << "\"" << " vr=\"" 00302 << de.GetVR() << "\" vm=\"" << de.GetVM() << "\" owner=\"" 00303 << t.GetOwner(); 00304 const char *name = de.GetName(); 00305 if( *name == 0 ) 00306 { 00307 std::cout << "\"/>\n"; 00308 } 00309 else 00310 { 00311 std::cout << "\" name=\"" << de.GetName() << "\"/>\n"; 00312 } 00313 } 00314 std::cout << "</dict>\n"; 00315 } 00316 00317 bool IsEmpty() const { return DictInternal.empty(); } 00318 protected: 00319 friend class Dicts; 00320 void LoadDefault(); 00321 00322 private: 00323 PrivateDict &operator=(const PrivateDict &_val); // purposely not implemented 00324 PrivateDict(const PrivateDict &_val); // purposely not implemented 00325 00326 MapDictEntry DictInternal; 00327 }; 00328 //----------------------------------------------------------------------------- 00329 inline std::ostream& operator<<(std::ostream& os, const PrivateDict &val) 00330 { 00331 PrivateDict::MapDictEntry::const_iterator it = val.DictInternal.begin(); 00332 for(;it != val.DictInternal.end(); ++it) 00333 { 00334 const PrivateTag &t = it->first; 00335 const DictEntry &de = it->second; 00336 os << t << " " << de << '\n'; 00337 } 00338 00339 return os; 00340 } 00341 00342 } // end namespace gdcm 00343 00344 #endif //GDCMDICT_H