# 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