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

Generated on Sat Dec 4 2010 08:58:49 for GDCM by doxygen 1.7.2
SourceForge.net Logo