# 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
    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