gdcmDict.h

Go to the documentation of this file.
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 
00106   const DictEntry &GetDictEntryByName(const char *name, Tag & tag) const
00107     {
00108     MapDictEntry::const_iterator it = 
00109       DictInternal.begin();
00110     if( name )
00111       {
00112       for(; it != DictInternal.end(); ++it)
00113         {
00114         if( strcmp( name, it->second.GetName() ) == 0 )
00115           {
00116           // Found a match !
00117           tag = it->first;
00118           break;
00119           }
00120         }
00121       }
00122     else
00123       {
00124       it = DictInternal.end();
00125       }
00126     if (it == DictInternal.end())
00127       {
00128       tag = Tag(0xffff,0xffff);
00129       it = DictInternal.find( tag );
00130       return it->second;
00131       }
00132     assert( DictInternal.count(tag) == 1 );
00133     return it->second;
00134     }
00135 
00136 protected:
00137   friend class Dicts;
00138   void LoadDefault();
00139 
00140 private:
00141   Dict &operator=(const Dict &_val); // purposely not implemented
00142   Dict(const Dict &_val); // purposely not implemented
00143 
00144   MapDictEntry DictInternal;
00145 };
00146 //-----------------------------------------------------------------------------
00147 inline std::ostream& operator<<(std::ostream& os, const Dict &val)
00148 {
00149   Dict::MapDictEntry::const_iterator it = val.DictInternal.begin();
00150   for(;it != val.DictInternal.end(); ++it)
00151     {
00152     const Tag &t = it->first;
00153     const DictEntry &de = it->second;
00154     os << t << " " << de << '\n';
00155     }
00156 
00157   return os;
00158 }
00159 
00160 // TODO
00161 // For private dict, element < 0x10 should automatically defined:
00162 // Name = "Private Creator"
00163 // ValueRepresentation = LO
00164 // ValueMultiplicity = 1
00165 // Owner = ""
00166 
00170 class GDCM_EXPORT PrivateDict
00171 {
00172   typedef std::map<PrivateTag, DictEntry> MapDictEntry;
00173   friend std::ostream& operator<<(std::ostream& os, const PrivateDict &val);
00174 public:
00175   PrivateDict() {}
00176   ~PrivateDict() {}
00177   void AddDictEntry(const PrivateTag &tag, const DictEntry &de)
00178     {
00179 #ifndef NDEBUG
00180     MapDictEntry::size_type s = DictInternal.size();
00181 #endif
00182     DictInternal.insert(
00183       MapDictEntry::value_type(tag, de));
00184 // The following code should only be used when manually constructing a Private.xml file by hand
00185 // it will get rid of VR::UN duplicate (ie. if a VR != VR::Un can be found)
00186 #if defined(NDEBUG) && 0
00187     if( s == DictInternal.size() )
00188       {
00189       MapDictEntry::iterator it = 
00190         DictInternal.find(tag);
00191       assert( it != DictInternal.end() );
00192       DictEntry &duplicate = it->second;
00193       assert( de.GetVR() == VR::UN || duplicate.GetVR() == VR::UN );
00194       assert( de.GetVR() != duplicate.GetVR() );
00195       if( duplicate.GetVR() == VR::UN )
00196         {
00197         assert( de.GetVR() != VR::UN );
00198         duplicate.SetVR( de.GetVR() );
00199         duplicate.SetVM( de.GetVM() );
00200         assert( GetDictEntry(tag).GetVR() != VR::UN );
00201         assert( GetDictEntry(tag).GetVR() == de.GetVR() );
00202         assert( GetDictEntry(tag).GetVM() == de.GetVM() );
00203         }
00204       return;
00205       }
00206 #endif
00207     assert( s < DictInternal.size() /*&& std::cout << tag << "," << de << std::endl*/ );
00208     }
00209   const DictEntry &GetDictEntry(const PrivateTag &tag) const
00210     {
00211     // if 0x10 -> return Private Creator
00212     MapDictEntry::const_iterator it = 
00213       DictInternal.find(tag);
00214     if (it == DictInternal.end())
00215       {
00216       //assert( 0 && "Impossible" );
00217       it = DictInternal.find( PrivateTag(0xffff,0xffff,"GDCM Private Sentinel" ) );
00218       assert (it != DictInternal.end());
00219       return it->second;
00220       }
00221     assert( DictInternal.count(tag) == 1 );
00222     return it->second;
00223     }
00224 
00225 
00226   void PrintXML() const
00227     {
00228     MapDictEntry::const_iterator it = DictInternal.begin();
00229     std::cout << "<dict edition=\"2008\">\n";
00230     for(;it != DictInternal.end(); ++it)
00231       {
00232       const PrivateTag &t = it->first;
00233       const DictEntry &de = it->second;
00234       std::cout << "  <entry group=\"" << std::hex << std::setw(4)
00235         << std::setfill('0') << t.GetGroup() << "\"" << 
00236         " element=\"xx" << std::setw(2) << std::setfill('0')<< t.GetElement() << "\"" << " vr=\"" 
00237         << de.GetVR() << "\" vm=\"" << de.GetVM() << "\" owner=\""
00238         << t.GetOwner();
00239       const char *name = de.GetName();
00240       if( *name == 0 )
00241         {
00242         std::cout << "\"/>\n";
00243         }
00244       else
00245         {
00246         std::cout << "\" name=\"" << de.GetName() << "\"/>\n";
00247         }
00248       }
00249     std::cout << "</dict>\n";
00250     }
00251 
00252   bool IsEmpty() const { return DictInternal.empty(); }
00253 protected:
00254   friend class Dicts;
00255   void LoadDefault();
00256 
00257 private:
00258   PrivateDict &operator=(const PrivateDict &_val); // purposely not implemented
00259   PrivateDict(const PrivateDict &_val); // purposely not implemented
00260 
00261   MapDictEntry DictInternal;
00262 };
00263 //-----------------------------------------------------------------------------
00264 inline std::ostream& operator<<(std::ostream& os, const PrivateDict &val)
00265 {
00266   PrivateDict::MapDictEntry::const_iterator it = val.DictInternal.begin();
00267   for(;it != val.DictInternal.end(); ++it)
00268     {
00269     const PrivateTag &t = it->first;
00270     const DictEntry &de = it->second;
00271     os << t << " " << de << '\n';
00272     }
00273 
00274   return os;
00275 }
00276 
00277 } // end namespace gdcm
00278 
00279 #endif //GDCMDICT_H

Generated on Sat Dec 4 2010 08:58:41 for GDCM by doxygen 1.7.2
SourceForge.net Logo