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