GDCM  2.2.0
gdcmTag.h
Go to the documentation of this file.
00001 /*=========================================================================
00002 
00003   Program: GDCM (Grassroots DICOM). A DICOM library
00004 
00005   Copyright (c) 2006-2011 Mathieu Malaterre
00006   All rights reserved.
00007   See Copyright.txt or http://gdcm.sourceforge.net/Copyright.html for details.
00008 
00009      This software is distributed WITHOUT ANY WARRANTY; without even
00010      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
00011      PURPOSE.  See the above copyright notice for more information.
00012 
00013 =========================================================================*/
00014 #ifndef GDCMTAG_H
00015 #define GDCMTAG_H
00016 
00017 #include "gdcmTypes.h"
00018 
00019 #include <iostream>
00020 #include <iomanip>
00021 
00022 namespace gdcm
00023 {
00024 
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 
00085   const uint16_t &operator[](const unsigned int &_id) const
00086     {
00087     assert(_id<2);
00088     return ElementTag.tags[_id];
00089     }
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     if( 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( (uint16_t)(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 = (uint16_t)(t.GetElement() << 8);
00195     uint16_t base = (uint16_t)(GetElement() << 8);
00196     SetElement( (uint16_t)((base >> 8) + element) );
00197     }
00198 
00201   bool IsPrivateCreator() const
00202     {
00203     return IsPrivate() && (GetElement() <= 0xFF && GetElement() >= 0x10);
00204     }
00205 
00207   bool IsIllegal() const
00208     {
00209     // DICOM reserved those groups:
00210     return GetGroup() == 0x0001 || GetGroup() == 0x0003 || GetGroup() == 0x0005 || GetGroup() == 0x0007
00211     // This is a very special case, in private group, one cannot use element [0x01,0x09] ...
00212 //      || (IsPrivate() && !IsPrivateCreator() && !IsGroupLength());
00213       || (IsPrivate() && GetElement() > 0x0 && GetElement() < 0x10 );
00214     }
00215 
00217   bool IsGroupLength() const
00218     {
00219     return GetElement() == 0x0;
00220     }
00221 
00223   bool IsGroupXX(const Tag &t) const
00224     {
00225     if( t.GetElement() == GetElement() )
00226       {
00227       if( t.IsPrivate() ) return false;
00228       uint16_t group = (uint16_t)((GetGroup() >> 8 ) << 8);
00229       return group == t.GetGroup();
00230       }
00231     return false;
00232     }
00233 
00239   bool ReadFromCommaSeparatedString(const char *str);
00240 
00243   bool ReadFromPipeSeparatedString(const char *str);
00244 
00247   std::string PrintAsPipeSeparatedString() const;
00248 
00249 private:
00250   union { uint32_t tag; uint16_t tags[2]; char bytes[4]; } ElementTag;
00251 };
00252 //-----------------------------------------------------------------------------
00253 inline std::istream& operator>>(std::istream &_is, Tag &_val)
00254 {
00255   char c;
00256   _is >> c;
00257   uint16_t a, b;
00258   _is >> std::hex >> a;
00259   //_is >> std::hex >> _val[0];
00260   //_is >> std::hex >> _val.ElementTag.tags[0];
00261   _is >> c;
00262   //_is >> _val[1];
00263   //_is >> std::hex >> _val.ElementTag.tags[1];
00264   _is >> std::hex >> b;
00265   _is >> c;
00266   _val.SetGroup( a );
00267   _val.SetElement( b );
00268   return _is;
00269 }
00270 
00271 inline std::ostream& operator<<(std::ostream &_os, const Tag &_val)
00272 {
00273   _os.setf( std::ios::right);
00274   _os << std::hex << '(' << std::setw( 4 ) << std::setfill( '0' )
00275     << _val[0] << ',' << std::setw( 4 ) << std::setfill( '0' )
00276     << _val[1] << ')' << std::setfill( ' ' ) << std::dec;
00277   return _os;
00278 }
00279 
00280 } // end namespace gdcm
00281 
00282 #endif //GDCMTAG_H

Generated on Tue Mar 27 2012 13:33:41 for GDCM by doxygen 1.8.0
SourceForge.net Logo