GDCM 2.0.17

gdcmVR.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 GDCMVR_H
00016 #define GDCMVR_H
00017 
00018 #include "gdcmTag.h"
00019 #include "gdcmTrace.h"
00020 #include "gdcmString.h"
00021 
00022 #include <iostream>
00023 #include <fstream>
00024 #include <assert.h>
00025 
00026 //these defines are here to ensure compilation on sunos gcc
00027 #if defined (CS)
00028 # undef CS
00029 #endif
00030 #if defined (DS)
00031 # undef DS
00032 #endif
00033 #if defined (SS)
00034 # undef SS
00035 #endif
00036 
00037 
00038 namespace gdcm
00039 {
00040 
00055 class GDCM_EXPORT VR
00056 {
00057 public:
00058   typedef enum {
00059     // Warning: Do not write if ( vr & VR::INVALID ) but if ( vr == VR::INVALID )
00060     INVALID = 0, // For Item/(Seq) Item Delimitation Item
00061     AE = 1,
00062     AS = 2,
00063     AT = 4,
00064     CS = 8,
00065     DA = 16,
00066     DS = 32,
00067     DT = 64,
00068     FD = 128,
00069     FL = 256,
00070     IS = 512,
00071     LO = 1024,
00072     LT = 2048,
00073     OB = 4096,
00074     OF = 8192,
00075     OW = 16384,
00076     PN = 32768,
00077     SH = 65536,
00078     SL = 131072,
00079     SQ = 262144,
00080     SS = 524288,
00081     ST = 1048576,
00082     TM = 2097152,
00083     UI = 4194304,
00084     UL = 8388608,
00085     UN = 16777216,
00086     US = 33554432,
00087     UT = 67108864,
00088     OB_OW = OB | OW,
00089     US_SS = US | SS,
00090     US_SS_OW = US | SS | OW,
00091     // The following do not have a VRString equivalent (ie cannot be found in PS 3.6)
00092     VL16 = AE | AS | AT | CS | DA | DS | DT | FD | FL | IS | LO | LT | PN | SH | SL | SS | ST | TM | UI | UL | US, // if( VR & VL16 ) => VR has its VL coded over 16bits
00093     VL32 = OB | OW | OF | SQ | UN | UT, // if( VR & VL32 ) => VR has its VL coded over 32bits
00094     VRASCII = AE | AS | CS | DA | DS | DT | IS | LO | LT | PN | SH | ST | TM | UI | UT,
00095     VRBINARY = AT | FL | FD | OB | OF | OW | SL | SQ | SS | UL | UN | US, // FIXME: UN ?
00096     // PS 3.5:
00097     // Data Elements with a VR of SQ, OF, OW, OB or UN shall always have a Value Multiplicity of one.
00098     // GDCM is adding a couple more: AS, LT, ST, UT
00099     VR_VM1 = AS | LT | ST | UT | SQ | OF | OW | OB | UN, // All those VR have a VM1
00100     VRALL = VRASCII | VRBINARY,
00101     VR_END = UT+1  // Invalid VR, need to be max(VRType)+1
00102   } VRType;
00103 
00104   static const char *GetVRString(VRType vr);
00105 
00106   // This function will only look at the very first two chars nothing else
00107   static VRType GetVRTypeFromFile(const char *vr);
00108 
00109   // You need to make sure end of string is \0
00110   static VRType GetVRType(const char *vr);
00111   static const char *GetVRStringFromFile(VRType vr);
00112 
00113   static bool IsValid(const char *vr);
00114   // Check if vr1 is valid against vr2,
00115   // Typically vr1 is read from the file and vr2 is taken from the dict
00116   static bool IsValid(const char *vr1, VRType vr2);
00117   //static bool IsValid(const VRType &vr1, const VRType &vr2);
00118   // Find out if the string read is byte swapped
00119   static bool IsSwap(const char *vr);
00120 
00121   // Size read on disk
00122   // FIXME: int ?
00123   int GetLength() const {
00124     return VR::GetLength(VRField);
00125   }
00126   unsigned int GetSizeof() const;
00127   static uint32_t GetLength(VRType vr) {
00128     //if( vr == VR::INVALID ) return 4;
00129     if( vr & VL32 )
00130       {
00131       return 4;
00132       }
00133     else
00134       return 2;
00135   }
00136 
00137   // Some use of template metaprograming with ugly macro
00138   static bool IsBinary(VRType vr);
00139   static bool IsASCII(VRType vr);
00140   // TODO: REMOVE ME
00141   static bool CanDisplay(VRType vr);
00142   // TODO: REMOVE ME
00143   static bool IsBinary2(VRType vr);
00144   // TODO: REMOVE ME
00145   static bool IsASCII2(VRType vr);
00146 
00147   VR(VRType vr = INVALID):VRField(vr) { }
00148   //VR(VR const &vr):VRField(vr.VRField) { }
00149   std::istream &Read(std::istream &is)
00150     {
00151     char vr[2];
00152     is.read(vr, 2);
00153     VRField = GetVRTypeFromFile(vr);
00154     assert( VRField != VR::VR_END );
00155     //assert( VRField != VR::INVALID );
00156     if( VRField == VR::INVALID ) throw Exception( "INVALID VR" );
00157     if( VRField & VL32 )
00158       {
00159 #if 0
00160       // For some reason this seems slower on my linux box...
00161       is.seekg(2, std::ios::cur );
00162 #else
00163       char dum[2];
00164       is.read(dum, 2);
00165       if( !(dum[0] == 0 && dum[1] == 0 ))
00166         {
00167         // JDDICOM_Sample4.dcm
00168         gdcmDebugMacro( "32bits VR contains non zero bytes. Skipped" );
00169         }
00170 #endif
00171       }
00172     return is;
00173     }
00174 
00175   const std::ostream &Write(std::ostream &os) const
00176     {
00177     VRType vrfield = VRField;
00178     gdcmAssertAlwaysMacro( !IsDual() );
00179     if( vrfield == VR::INVALID )
00180       {
00181       //vrfield = VR::UN;
00182       }
00183     const char *vr = GetVRString(vrfield);
00184     //assert( strlen( vr ) == 2 );
00185     assert( vr[0] && vr[1] && vr[2] == 0 );
00186     os.write(vr, 2);
00187     // See PS 3.5, Data Element Structure With Explicit VR
00188     if( vrfield & VL32 )
00189       {
00190       const char dum[2] = {0, 0};
00191       os.write(dum,2);
00192       }
00193     return os;
00194     }
00195   friend std::ostream &operator<<(std::ostream &os, const VR &vr);
00196 
00197   operator VRType () const { return VRField; }
00198 
00199   unsigned int GetSize() const;
00200 
00201   bool Compatible(VR const &vr) const;
00202 
00203   bool IsVRFile() const;
00204 
00205   bool IsDual() const;
00206 
00207 private:
00208   // Internal function that map a VRType to an index in the VRStrings table
00209   static int GetIndex(VRType vr);
00210   VRType VRField;
00211 };
00212 //-----------------------------------------------------------------------------
00213 inline std::ostream &operator<<(std::ostream &_os, const VR &val)
00214 {
00215   //_os << VR::GetVRStringFromFile(val.VRField);
00216   _os << VR::GetVRString(val.VRField);
00217   return _os;
00218 }
00219 
00220 // Apparently SWIG is not happy with something, somewhere below...
00221 #ifndef SWIG
00222 
00223 // Tells whether VR Type is ASCII or Binary
00224 template<int T> struct VRToEncoding;
00225 // Convert from VR Type to real underlying type
00226 template<int T> struct VRToType;
00227 #define TYPETOENCODING(type,rep, rtype)         \
00228   template<> struct VRToEncoding<VR::type>    \
00229   { enum { Mode = VR::rep }; };                 \
00230   template<> struct VRToType<VR::type>        \
00231   { typedef rtype Type; };
00232 
00233 
00234 // Do not use me
00235 struct UI { char Internal[64+1];
00236   friend std::ostream& operator<<(std::ostream &_os, const UI &_val);
00237 };
00238 inline std::ostream& operator<<(std::ostream &_os, const UI &_val)
00239 {
00240   _os << _val.Internal;
00241   return _os;
00242 }
00243 
00244 typedef String<'\\',16> AEComp;
00245 typedef String<'\\',64> ASComp;
00246 typedef String<'\\',16> CSComp;
00247 typedef String<'\\',64> DAComp;
00248 typedef String<'\\',64> DTComp;
00249 typedef String<'\\',64> LOComp;
00250 typedef String<'\\',64> LTComp;
00251 typedef String<'\\',64> PNComp;
00252 typedef String<'\\',64> SHComp;
00253 typedef String<'\\',64> STComp;
00254 typedef String<'\\',64> TMComp;
00255 typedef String<'\\',64,0> UIComp;
00256 typedef String<'\\',64> UTComp;
00257 
00258 
00259 // TODO: Could be generated from XML file
00260 TYPETOENCODING(AE,VRASCII ,AEComp)
00261 TYPETOENCODING(AS,VRASCII ,ASComp)
00262 TYPETOENCODING(AT,VRBINARY,Tag)
00263 TYPETOENCODING(CS,VRASCII ,CSComp)
00264 TYPETOENCODING(DA,VRASCII ,DAComp)
00265 TYPETOENCODING(DS,VRASCII ,double)
00266 TYPETOENCODING(DT,VRASCII ,DTComp)
00267 TYPETOENCODING(FL,VRBINARY,float)
00268 TYPETOENCODING(FD,VRBINARY,double)
00269 TYPETOENCODING(IS,VRASCII ,int32_t)
00270 TYPETOENCODING(LO,VRASCII ,LOComp)
00271 TYPETOENCODING(LT,VRASCII ,LTComp)
00272 TYPETOENCODING(OB,VRBINARY,uint8_t)
00273 TYPETOENCODING(OF,VRBINARY,float)
00274 TYPETOENCODING(OW,VRBINARY,uint16_t)
00275 TYPETOENCODING(PN,VRASCII ,PNComp)
00276 TYPETOENCODING(SH,VRASCII ,SHComp)
00277 TYPETOENCODING(SL,VRBINARY,int32_t)
00278 TYPETOENCODING(SQ,VRBINARY,unsigned char) // FIXME
00279 TYPETOENCODING(SS,VRBINARY,int16_t)
00280 TYPETOENCODING(ST,VRASCII ,STComp)
00281 TYPETOENCODING(TM,VRASCII ,TMComp)
00282 TYPETOENCODING(UI,VRASCII ,UIComp)
00283 TYPETOENCODING(UL,VRBINARY,uint32_t)
00284 TYPETOENCODING(UN,VRBINARY,uint8_t) // FIXME ?
00285 TYPETOENCODING(US,VRBINARY,uint16_t)
00286 TYPETOENCODING(UT,VRASCII ,UTComp)
00287 
00288 #define VRTypeTemplateCase(type) \
00289   case VR::type: \
00290     return sizeof ( VRToType<VR::type>::Type );
00291 
00292 inline unsigned int VR::GetSize() const
00293 {
00294   switch(VRField)
00295   {
00296     VRTypeTemplateCase(AE)
00297     VRTypeTemplateCase(AS)
00298     VRTypeTemplateCase(AT)
00299     VRTypeTemplateCase(CS)
00300     VRTypeTemplateCase(DA)
00301     VRTypeTemplateCase(DS)
00302     VRTypeTemplateCase(DT)
00303     VRTypeTemplateCase(FL)
00304     VRTypeTemplateCase(FD)
00305     VRTypeTemplateCase(IS)
00306     VRTypeTemplateCase(LO)
00307     VRTypeTemplateCase(LT)
00308     VRTypeTemplateCase(OB)
00309     VRTypeTemplateCase(OF)
00310     VRTypeTemplateCase(OW)
00311     VRTypeTemplateCase(PN)
00312     VRTypeTemplateCase(SH)
00313     VRTypeTemplateCase(SL)
00314     VRTypeTemplateCase(SQ)
00315     VRTypeTemplateCase(SS)
00316     VRTypeTemplateCase(ST)
00317     VRTypeTemplateCase(TM)
00318     VRTypeTemplateCase(UI)
00319     VRTypeTemplateCase(UL)
00320     VRTypeTemplateCase(UN)
00321     VRTypeTemplateCase(US)
00322     VRTypeTemplateCase(UT)
00323     case VR::US_SS:
00324       return 2;
00325     default:
00326        assert( 0 && "should not" );
00327   }
00328   return 0;
00329 }
00330 #endif // SWIG
00331 
00332 
00333 } // end namespace gdcm
00334 
00335 #endif //GDCMVR_H

Generated on Wed Feb 2 2011 19:21:02 for GDCM by doxygen 1.7.3
SourceForge.net Logo