GDCM 2.2.0

- Main Page
- Related Pages
- Namespaces
- Classes
- Files
- Directories
- Examples

- File List
- File Members

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