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

Generated on Fri Mar 30 2012 12:44:08 for GDCM by doxygen 1.8.0
SourceForge.net Logo