gdcmTag.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 GDCMTAG_H
00016 #define GDCMTAG_H
00017 
00018 #include "gdcmTypes.h"
00019 
00020 #include <iostream>
00021 #include <iomanip>
00022 
00023 namespace gdcm
00024 {
00025 
00039 class GDCM_EXPORT Tag
00040 {
00041 public:
00043   Tag(uint16_t group, uint16_t element) {
00044     ElementTag.tags[0] = group; ElementTag.tags[1] = element;
00045   }
00048   Tag(uint32_t tag = 0) {
00049     SetElementTag(tag);
00050   }
00051 
00052   friend std::ostream& operator<<(std::ostream &_os, const Tag &_val);
00053   friend std::istream& operator>>(std::istream &_is, Tag &_val);
00054 
00056   uint16_t GetGroup() const { return ElementTag.tags[0]; }
00058   uint16_t GetElement() const { return ElementTag.tags[1]; }
00060   void SetGroup(uint16_t group) { ElementTag.tags[0] = group; }
00062   void SetElement(uint16_t element) { ElementTag.tags[1] = element; }
00064   void SetElementTag(uint16_t group, uint16_t element) {
00065     ElementTag.tags[0] = group; ElementTag.tags[1] = element;
00066   }
00067 
00069   uint32_t GetElementTag() const {
00070 #ifndef GDCM_WORDS_BIGENDIAN
00071     return (ElementTag.tag<<16) | (ElementTag.tag>>16);
00072 #else
00073     return ElementTag.tag;
00074 #endif
00075   }
00076 
00078   void SetElementTag(uint32_t tag) {
00079 #ifndef GDCM_WORDS_BIGENDIAN
00080     tag = ( (tag<<16) | (tag>>16) );
00081 #endif
00082     ElementTag.tag = tag;
00083   }
00084 
00086   const uint16_t &operator[](const unsigned int &_id) const
00087     {
00088     assert(_id<2);
00089     return ElementTag.tags[_id];
00090     }
00092   uint16_t &operator[](const unsigned int &_id)
00093     {
00094     assert(_id<2);
00095     return ElementTag.tags[_id];
00096     }
00097 
00098   Tag &operator=(const Tag &_val)
00099     {
00100     ElementTag.tag = _val.ElementTag.tag;
00101     return *this;
00102     }
00103 
00104   bool operator==(const Tag &_val) const
00105     {
00106     return ElementTag.tag == _val.ElementTag.tag;
00107     }
00108   bool operator!=(const Tag &_val) const
00109     {
00110     return ElementTag.tag != _val.ElementTag.tag;
00111     }
00112 
00115   // FIXME FIXME FIXME TODO
00116   // the following is pretty dumb. Since we have control over who is group
00117   // and who is element, we should reverse them in little endian and big endian case
00118   // since what we really want is fast comparison and not garantee that group is in #0
00119   // ...
00120   bool operator<(const Tag &_val) const
00121     {
00122 #ifndef GDCM_WORDS_BIGENDIAN
00123     if( ElementTag.tags[0] < _val.ElementTag.tags[0] )
00124       return true;
00125     if( ElementTag.tags[0] == _val.ElementTag.tags[0]
00126       && ElementTag.tags[1] <  _val.ElementTag.tags[1] )
00127       return true;
00128     return false;
00129 #else
00130     // Plain comparison is enough!
00131     return ( ElementTag.tag < _val.ElementTag.tag );
00132 #endif
00133     }
00134   bool operator<=(const Tag &t2) const
00135     {
00136     const Tag &t1 = *this;
00137     return t1 == t2 || t1 < t2;
00138     }
00139 
00140   Tag(const Tag &_val)
00141     {
00142     ElementTag.tag = _val.ElementTag.tag;
00143     }
00145   uint32_t GetLength() const { return 4; }
00146 
00151   bool IsPublic() const { return !(ElementTag.tags[0] % 2); }
00152 
00156   bool IsPrivate() const { return !IsPublic(); }
00157 
00158   //-----------------------------------------------------------------------------
00160   template <typename TSwap>
00161   std::istream &Read(std::istream &is)
00162     {
00163     is.read(ElementTag.bytes, 4);
00164     TSwap::SwapArray(ElementTag.tags, 2);
00165     return is;
00166     }
00167 
00169   template <typename TSwap>
00170   const std::ostream &Write(std::ostream &os) const
00171     {
00172     uint16_t copy[2];
00173     copy[0]= ElementTag.tags[0];
00174     copy[1]= ElementTag.tags[1];
00175     TSwap::SwapArray(copy, 2);
00176     return os.write((char*)(&copy), 4);
00177     }
00178 
00180   Tag GetPrivateCreator() const
00181     {
00182     // See PS 3.5 - 7.8.1 PRIVATE DATA ELEMENT TAGS
00183     // eg: 0x0123,0x1425 -> 0x0123,0x0014
00184     assert( IsPrivate() && !IsPrivateCreator() );
00185     Tag r = *this;
00186     r.SetElement( GetElement() >> 8 );
00187     return r;
00188     }
00190   void SetPrivateCreator(Tag const &t)
00191     {
00192     // See PS 3.5 - 7.8.1 PRIVATE DATA ELEMENT TAGS
00193     // eg: 0x0123,0x0045 -> 0x0123,0x4567
00194     assert( t.IsPrivate() /*&& t.IsPrivateCreator()*/ );
00195     uint16_t element = t.GetElement() << 8;
00196     uint16_t base = GetElement() << 8;
00197     SetElement( (base >> 8) + element );
00198     }
00199 
00202   bool IsPrivateCreator() const
00203     {
00204     return IsPrivate() && (GetElement() <= 0xFF && GetElement() >= 0x10);
00205     }
00206 
00208   bool IsIllegal() const
00209     {
00210     // DICOM reserved those groups:
00211     return GetGroup() == 0x0001 || GetGroup() == 0x0003 || GetGroup() == 0x0005 || GetGroup() == 0x0007
00212     // This is a very special case, in private group, one cannot use element [0x01,0x09] ...
00213 //      || (IsPrivate() && !IsPrivateCreator() && !IsGroupLength());
00214       || (IsPrivate() && GetElement() > 0x0 && GetElement() < 0x10 );
00215     }
00216 
00218   bool IsGroupLength() const
00219     {
00220     return GetElement() == 0x0;
00221     }
00222 
00224   bool IsGroupXX(const Tag &t) const
00225     {
00226     if( t.GetElement() == GetElement() )
00227       {
00228       if( t.IsPrivate() ) return false;
00229       uint16_t group = (GetGroup() >> 8 ) << 8;
00230       return group == t.GetGroup();
00231       }
00232     return false;
00233     }
00234 
00240   bool ReadFromCommaSeparatedString(const char *str);
00241 
00244   bool ReadFromPipeSeparatedString(const char *str);
00245 
00248   std::string PrintAsPipeSeparatedString() const;
00249 
00250 private:
00251   union { uint32_t tag; uint16_t tags[2]; char bytes[4]; } ElementTag;
00252 };
00253 //-----------------------------------------------------------------------------
00254 inline std::istream& operator>>(std::istream &_is, Tag &_val)
00255 {
00256   char c;
00257   _is >> c;
00258   uint16_t a, b;
00259   _is >> std::hex >> a;
00260   //_is >> std::hex >> _val[0];
00261   //_is >> std::hex >> _val.ElementTag.tags[0];
00262   _is >> c;
00263   //_is >> _val[1];
00264   //_is >> std::hex >> _val.ElementTag.tags[1];
00265   _is >> std::hex >> b;
00266   _is >> c;
00267   _val.SetGroup( a );
00268   _val.SetElement( b );
00269   return _is;
00270 }
00271 
00272 inline std::ostream& operator<<(std::ostream &_os, const Tag &_val)
00273 {
00274   _os.setf( std::ios::right);
00275   _os << std::hex << '(' << std::setw( 4 ) << std::setfill( '0' )
00276     << _val[0] << ',' << std::setw( 4 ) << std::setfill( '0' )
00277     << _val[1] << ')' << std::setfill( ' ' ) << std::dec;
00278   return _os;
00279 }
00280 
00281 } // end namespace gdcm
00282 
00283 #endif //GDCMTAG_H
00284 

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