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-2009 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 
00038 class GDCM_EXPORT Tag
00039 {
00040 public:
00042   Tag(uint16_t group, uint16_t element) {
00043     ElementTag.tags[0] = group; ElementTag.tags[1] = element;
00044   }
00047   Tag(uint32_t tag = 0) {
00048     SetElementTag(tag);
00049   } 
00050 
00051   friend std::ostream& operator<<(std::ostream &_os, const Tag &_val);
00052   friend std::istream& operator>>(std::istream &_is, Tag &_val);
00053 
00055   uint16_t GetGroup() const { return ElementTag.tags[0]; }
00057   uint16_t GetElement() const { return ElementTag.tags[1]; }
00059   void SetGroup(uint16_t group) { ElementTag.tags[0] = group; }
00061   void SetElement(uint16_t element) { ElementTag.tags[1] = element; }
00063   void SetElementTag(uint16_t group, uint16_t element) {
00064     ElementTag.tags[0] = group; ElementTag.tags[1] = element;
00065   }
00066 
00068   uint32_t GetElementTag() const { 
00069 #ifndef GDCM_WORDS_BIGENDIAN    
00070     return (ElementTag.tag<<16) | (ElementTag.tag>>16);
00071 #else
00072     return ElementTag.tag;
00073 #endif
00074   }
00075  
00077   void SetElementTag(uint32_t tag) {
00078 #ifndef GDCM_WORDS_BIGENDIAN
00079     tag = ( (tag<<16) | (tag>>16) );
00080 #endif
00081     ElementTag.tag = tag;
00082   }
00083 
00084   // \brief Returns the Group or Element of the given Tag, depending on id (0/1)
00085   const uint16_t &operator[](const unsigned int &_id) const
00086     {
00087     assert(_id<2);
00088     return ElementTag.tags[_id];
00089     }
00090   // \brief Returns the Group or Element of the given Tag, depending on id (0/1)    
00091   uint16_t &operator[](const unsigned int &_id)
00092     {
00093     assert(_id<2);
00094     return ElementTag.tags[_id];
00095     }
00096 
00097   Tag &operator=(const Tag &_val)
00098     {
00099     ElementTag.tag = _val.ElementTag.tag;
00100     return *this;
00101     }
00102 
00103   bool operator==(const Tag &_val) const
00104     {
00105     return ElementTag.tag == _val.ElementTag.tag;
00106     }
00107   bool operator!=(const Tag &_val) const
00108     {
00109     return ElementTag.tag != _val.ElementTag.tag;
00110     }
00111 
00114   // FIXME FIXME FIXME TODO
00115   // the following is pretty dumb. Since we have control over who is group
00116   // and who is element, we should reverse them in little endian and big endian case
00117   // since what we really want is fast comparison and not garantee that group is in #0
00118   // ...
00119   bool operator<(const Tag &_val) const
00120     {
00121 #ifndef GDCM_WORDS_BIGENDIAN
00122     if( ElementTag.tags[0] < _val.ElementTag.tags[0] )
00123       return true;
00124     if( ElementTag.tags[0] == _val.ElementTag.tags[0]
00125      && ElementTag.tags[1] <  _val.ElementTag.tags[1] )
00126       return true;
00127     return false;
00128 #else
00129      // Plain comparison is enough!
00130      return ( ElementTag.tag < _val.ElementTag.tag );
00131 #endif
00132    }      
00133   bool operator<=(const Tag &t2) const
00134     {
00135     const Tag &t1 = *this;
00136     return t1 == t2 || t1 < t2;
00137     }
00138 
00139   Tag(const Tag &_val)
00140     {
00141     ElementTag.tag = _val.ElementTag.tag;
00142     }
00144   uint32_t GetLength() const { return 4; }
00145 
00150   bool IsPublic() const { return !(ElementTag.tags[0] % 2); }
00151 
00155   bool IsPrivate() const { return !IsPublic(); }
00156 
00157   //-----------------------------------------------------------------------------
00159   template <typename TSwap>
00160   std::istream &Read(std::istream &is)
00161     {
00162     is.read(ElementTag.bytes, 4);
00163     TSwap::SwapArray(ElementTag.tags, 2);
00164     return is;
00165     }
00166 
00168   template <typename TSwap>
00169   const std::ostream &Write(std::ostream &os) const
00170     {
00171     uint16_t copy[2];
00172     copy[0]= ElementTag.tags[0];
00173     copy[1]= ElementTag.tags[1];
00174     TSwap::SwapArray(copy, 2);
00175     return os.write((char*)(&copy), 4);
00176     }
00177 
00179   Tag GetPrivateCreator() const
00180     {
00181     // See PS 3.5 - 7.8.1 PRIVATE DATA ELEMENT TAGS
00182     // eg: 0x0123,0x1425 -> 0x0123,0x0014
00183     assert( IsPrivate() && !IsPrivateCreator() );
00184     Tag r = *this;
00185     r.SetElement( GetElement() >> 8 );
00186     return r;
00187     }
00189   void SetPrivateCreator(Tag const &t)
00190     {
00191     // See PS 3.5 - 7.8.1 PRIVATE DATA ELEMENT TAGS
00192     // eg: 0x0123,0x0045 -> 0x0123,0x4567
00193     assert( t.IsPrivate() /*&& t.IsPrivateCreator()*/ );
00194     uint16_t element = t.GetElement() << 8;
00195     uint16_t base = GetElement() << 8;
00196     SetElement( (base >> 8) + element );
00197     }
00198 
00200   bool IsPrivateCreator() const
00201     {
00202     return IsPrivate() && (GetElement() <= 0xFF && GetElement() >= 0x10);
00203     }
00204 
00206   bool IsIllegal() const 
00207     {
00208     // DICOM reserved those groups:
00209     return GetGroup() == 0x0001 || GetGroup() == 0x0003 || GetGroup() == 0x0005 || GetGroup() == 0x0007
00210     // This is a very special case, in private group, one cannot use element [0x01,0x09] ...
00211 //      || (IsPrivate() && !IsPrivateCreator() && !IsGroupLength());
00212       || (IsPrivate() && GetElement() > 0x0 && GetElement() < 0x10 );
00213     }
00214 
00216   bool IsGroupLength() const
00217     {
00218     return GetElement() == 0x0;
00219     }
00220 
00222   bool IsGroupXX(const Tag &t) const
00223     {
00224     if( t.GetElement() == GetElement() )
00225       {
00226       if( t.IsPrivate() ) return false;
00227       uint16_t group = (GetGroup() >> 8 ) << 8;
00228       return group == t.GetGroup();
00229       }
00230     return false;
00231     }
00232 
00238   bool ReadFromCommaSeparatedString(const char *str);
00239 
00242   bool ReadFromPipeSeparatedString(const char *str);
00243 
00246   std::string PrintAsPipeSeparatedString() const;
00247 
00248 private:
00249   union { uint32_t tag; uint16_t tags[2]; char bytes[4]; } ElementTag;
00250 };
00251 //-----------------------------------------------------------------------------
00252 inline std::istream& operator>>(std::istream &_is, Tag &_val)
00253 {
00254   char c;
00255   _is >> c;
00256   uint16_t a, b;
00257   _is >> std::hex >> a;
00258   //_is >> std::hex >> _val[0];
00259   //_is >> std::hex >> _val.ElementTag.tags[0];
00260   _is >> c;
00261   //_is >> _val[1];
00262   //_is >> std::hex >> _val.ElementTag.tags[1];
00263   _is >> std::hex >> b;
00264   _is >> c;
00265   _val.SetGroup( a );
00266   _val.SetElement( b );
00267   return _is;
00268 }
00269 
00270 inline std::ostream& operator<<(std::ostream &_os, const Tag &_val)
00271 {
00272   _os.setf( std::ios::right);
00273   _os << std::hex << '(' << std::setw( 4 ) << std::setfill( '0' )
00274     << _val[0] << ',' << std::setw( 4 ) << std::setfill( '0' )
00275     << _val[1] << ')' << std::setfill( ' ' ) << std::dec;
00276   return _os;
00277 }
00278 
00279 } // end namespace gdcm
00280 
00281 #endif //__gdcmTag_h
00282 

Generated on Sun Mar 7 03:17:21 2010 for GDCM by doxygen 1.6.3
SourceForge.net Logo