GDCM  2.2.0
gdcmElement.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 GDCMELEMENT_H
00015 #define GDCMELEMENT_H
00016 
00017 #include "gdcmTypes.h"
00018 #include "gdcmVR.h"
00019 #include "gdcmTag.h"
00020 #include "gdcmVM.h"
00021 #include "gdcmByteValue.h"
00022 #include "gdcmDataElement.h"
00023 #include "gdcmSwapper.h"
00024 
00025 #include <string>
00026 #include <vector>
00027 #include <sstream>
00028 #include <limits>
00029 #include <cmath>
00030 #include <cstring>
00031 
00032 namespace gdcm
00033 {
00034 
00035 // Forward declaration
00041 template<int T> class EncodingImplementation;
00042 
00048 template<int TVR, int TVM>
00049 class Element
00050 {
00051 public:
00052   typename VRToType<TVR>::Type Internal[VMToLength<TVM>::Length];
00053   typedef typename VRToType<TVR>::Type Type;
00054 
00055   static VR  GetVR()  { return (VR::VRType)TVR; }
00056   static VM  GetVM()  { return (VM::VMType)TVM; }
00057 
00058   unsigned long GetLength() const {
00059     return VMToLength<TVM>::Length;
00060   }
00061   // Implementation of Print is common to all Mode (ASCII/Binary)
00062   // TODO: Can we print a \ when in ASCII...well I don't think so
00063   // it would mean we used a bad VM then, right ?
00064   void Print(std::ostream &_os) const {
00065     _os << Internal[0]; // VM is at least garantee to be one
00066     for(int i=1; i<VMToLength<TVM>::Length; ++i)
00067       _os << "," << Internal[i];
00068     }
00069 
00070   const typename VRToType<TVR>::Type *GetValues() const {
00071     return Internal;
00072   }
00073   const typename VRToType<TVR>::Type &GetValue(unsigned int idx = 0) const {
00074     assert( idx < VMToLength<TVM>::Length );
00075     return Internal[idx];
00076   }
00077   typename VRToType<TVR>::Type &GetValue(unsigned int idx = 0) {
00078     assert( idx < VMToLength<TVM>::Length );
00079     return Internal[idx];
00080   }
00081   typename VRToType<TVR>::Type operator[] (unsigned int idx) const {
00082     return GetValue(idx);
00083   }
00084   void SetValue(typename VRToType<TVR>::Type v, unsigned int idx = 0) {
00085     assert( idx < VMToLength<TVM>::Length );
00086     Internal[idx] = v;
00087   }
00088 
00089   void SetFromDataElement(DataElement const &de) {
00090     const ByteValue *bv = de.GetByteValue();
00091     if( !bv ) return;
00092 #ifdef GDCM_WORDS_BIGENDIAN
00093     if( de.GetVR() == VR::UN /*|| de.GetVR() == VR::INVALID*/ )
00094 #else
00095     if( de.GetVR() == VR::UN || de.GetVR() == VR::INVALID )
00096 #endif
00097       {
00098       Set(de.GetValue());
00099       }
00100     else
00101       {
00102       SetNoSwap(de.GetValue());
00103       }
00104   }
00105 
00106   DataElement GetAsDataElement() const {
00107     DataElement ret;
00108     std::ostringstream os;
00109     EncodingImplementation<VRToEncoding<TVR>::Mode>::Write(Internal,
00110       GetLength(),os);
00111     ret.SetVR( (VR::VRType)TVR );
00112     assert( ret.GetVR() != VR::SQ );
00113     if( (VR::VRType)VRToEncoding<TVR>::Mode == VR::VRASCII )
00114       {
00115       if( GetVR() != VR::UI )
00116         {
00117         if( os.str().size() % 2 )
00118           {
00119           os << " ";
00120           }
00121         }
00122       }
00123     VL::Type osStrSize = (VL::Type)os.str().size();
00124     ret.SetByteValue( os.str().c_str(), osStrSize );
00125 
00126     return ret;
00127   }
00128 
00129   void Read(std::istream &_is) {
00130     return EncodingImplementation<VRToEncoding<TVR>::Mode>::Read(Internal,
00131       GetLength(),_is);
00132     }
00133   void Write(std::ostream &_os) const {
00134     return EncodingImplementation<VRToEncoding<TVR>::Mode>::Write(Internal,
00135       GetLength(),_os);
00136     }
00137 
00138   // FIXME: remove this function
00139   // this is only used in gdcm::SplitMosaicFilter / to pass value of a CSAElement
00140   void Set(Value const &v) {
00141     const ByteValue *bv = dynamic_cast<const ByteValue*>(&v);
00142     if( bv ) {
00143       //memcpy(Internal, bv->GetPointer(), bv->GetLength());
00144       std::stringstream ss;
00145       std::string s = std::string( bv->GetPointer(), bv->GetLength() );
00146       ss.str( s );
00147       EncodingImplementation<VRToEncoding<TVR>::Mode>::Read(Internal,
00148         GetLength(),ss);
00149     }
00150   }
00151 protected:
00152   void SetNoSwap(Value const &v) {
00153     const ByteValue *bv = dynamic_cast<const ByteValue*>(&v);
00154     assert( bv ); // That would be bad...
00155     //memcpy(Internal, bv->GetPointer(), bv->GetLength());
00156     std::stringstream ss;
00157     std::string s = std::string( bv->GetPointer(), bv->GetLength() );
00158     ss.str( s );
00159     EncodingImplementation<VRToEncoding<TVR>::Mode>::ReadNoSwap(Internal,
00160       GetLength(),ss);
00161   }
00162 };
00163 
00164 struct ignore_char {
00165   ignore_char(char c): m_char(c) {}
00166   char m_char;
00167 };
00168 ignore_char const backslash('\\');
00169 
00170   inline std::istream& operator>> (std::istream& in, ignore_char const& ic) {
00171     if (!in.eof())
00172       in.clear(in.rdstate() & ~std::ios_base::failbit);
00173     if (in.get() != ic.m_char)
00174       in.setstate(std::ios_base::failbit);
00175     return in;
00176   }
00177 
00178 
00179 // Implementation to perform formatted read and write
00180 template<> class EncodingImplementation<VR::VRASCII> {
00181 public:
00182   template<typename T> // FIXME this should be VRToType<TVR>::Type
00183   static inline void ReadComputeLength(T* data, unsigned int &length,
00184                           std::istream &_is) {
00185     assert( data );
00186     //assert( length ); // != 0
00187     length = 0;
00188     assert( _is );
00189 #if 0
00190     char sep;
00191     while( _is >> data[length++] )
00192       {
00193       // Get the separator in between the values
00194       assert( _is );
00195       _is.get(sep);
00196       assert( sep == '\\' || sep == ' ' ); // FIXME: Bad use of assert
00197       if( sep == ' ' ) length--; // FIXME
00198       }
00199 #else
00200   while( _is >> std::ws >> data[length++] >> std::ws >> backslash )
00201     {
00202     }
00203 #endif
00204     }
00205 
00206   template<typename T> // FIXME this should be VRToType<TVR>::Type
00207   static inline void Read(T* data, unsigned long length,
00208                           std::istream &_is) {
00209     assert( data );
00210     assert( length ); // != 0
00211     assert( _is );
00212     // FIXME BUG: what if >> operation fails ?
00213     // gdcmData/MR00010001.dcm / SpacingBetweenSlices
00214     _is >> std::ws >> data[0];
00215     char sep;
00216     //std::cout << "GetLength: " << af->GetLength() << std::endl;
00217     for(unsigned long i=1; i<length;++i) {
00218       assert( _is );
00219       // Get the separator in between the values
00220       _is >> std::ws >> sep; //_is.get(sep);
00221       assert( sep == '\\' ); // FIXME: Bad use of assert
00222       _is >> std::ws >> data[i];
00223       }
00224     }
00225 
00226   template<typename T>
00227   static inline void ReadNoSwap(T* data, unsigned long length,
00228                           std::istream &_is) {
00229     Read(data,length,_is);
00230 }
00231   template<typename T>
00232   static inline void Write(const T* data, unsigned long length,
00233                            std::ostream &_os)  {
00234     assert( data );
00235     assert( length );
00236     assert( _os );
00237     _os << data[0];
00238     for(unsigned long i=1; i<length; ++i) {
00239       assert( _os );
00240       _os << "\\" << data[i];
00241       }
00242     }
00243 };
00244 
00245 template < typename Float >
00246 std::string to_string ( Float data ) {
00247   std::stringstream in;
00248   // in.imbue(std::locale::classic()); // This is not required AFAIK
00249   unsigned long const digits =
00250     static_cast< unsigned long >(
00251     - std::log( std::numeric_limits<Float>::epsilon() )
00252     / std::log( 10.0 ) );
00253   if ( in << std::dec << std::setprecision(/*2+*/digits) << data ) {
00254     return ( in.str() );
00255   } else {
00256     throw "Impossible Conversion"; // should not happen ...
00257   }
00258 }
00259 
00260 /* Writing VR::DS is not that easy after all */
00261 // http://groups.google.com/group/comp.lang.c++/browse_thread/thread/69ccd26f000a0802
00262 template<> inline void EncodingImplementation<VR::VRASCII>::Write(const float * data, unsigned long length, std::ostream &_os)  {
00263     assert( data );
00264     assert( length );
00265     assert( _os );
00266     _os << to_string(data[0]);
00267     for(unsigned long i=1; i<length; ++i) {
00268       assert( _os );
00269       _os << "\\" << to_string(data[i]);
00270       }
00271     }
00272 
00273 template<> inline void EncodingImplementation<VR::VRASCII>::Write(const double* data, unsigned long length, std::ostream &_os)  {
00274     assert( data );
00275     assert( length );
00276     assert( _os );
00277     _os << to_string(data[0]);
00278     for(unsigned long i=1; i<length; ++i) {
00279       assert( _os );
00280       _os << "\\" << to_string(data[i]);
00281       }
00282     }
00283 
00284 
00285 // Implementation to perform binary read and write
00286 // TODO rewrite operation so that either:
00287 // #1. dummy implementation use a pointer to Internal and do ++p (faster)
00288 // #2. Actually do some meta programming to unroll the loop
00289 // (no notion of order in VM ...)
00290 template<> class EncodingImplementation<VR::VRBINARY> {
00291 public:
00292   template<typename T> // FIXME this should be VRToType<TVR>::Type
00293     static inline void ReadComputeLength(T* data, unsigned int &length,
00294       std::istream &_is) {
00295     const unsigned int type_size = sizeof(T);
00296     assert( data ); // Can we read from pointer ?
00297     //assert( length );
00298     length /= type_size;
00299     assert( _is ); // Is stream valid ?
00300     _is.read( reinterpret_cast<char*>(data+0), type_size);
00301     for(unsigned long i=1; i<length; ++i) {
00302       assert( _is );
00303       _is.read( reinterpret_cast<char*>(data+i), type_size );
00304     }
00305     }
00306   template<typename T>
00307   static inline void ReadNoSwap(T* data, unsigned long length,
00308     std::istream &_is) {
00309     const unsigned int type_size = sizeof(T);
00310     assert( data ); // Can we read from pointer ?
00311     assert( length );
00312     assert( _is ); // Is stream valid ?
00313     _is.read( reinterpret_cast<char*>(data+0), type_size);
00314     for(unsigned long i=1; i<length; ++i) {
00315       assert( _is );
00316       _is.read( reinterpret_cast<char*>(data+i), type_size );
00317     }
00318     //ByteSwap<T>::SwapRangeFromSwapCodeIntoSystem(data,
00319     //  _is.GetSwapCode(), length);
00320     //SwapperNoOp::SwapArray(data,length);
00321   }
00322   template<typename T>
00323   static inline void Read(T* data, unsigned long length,
00324     std::istream &_is) {
00325     const unsigned int type_size = sizeof(T);
00326     assert( data ); // Can we read from pointer ?
00327     assert( length );
00328     assert( _is ); // Is stream valid ?
00329     _is.read( reinterpret_cast<char*>(data+0), type_size);
00330     for(unsigned long i=1; i<length; ++i) {
00331       assert( _is );
00332       _is.read( reinterpret_cast<char*>(data+i), type_size );
00333     }
00334     //ByteSwap<T>::SwapRangeFromSwapCodeIntoSystem(data,
00335     //  _is.GetSwapCode(), length);
00336     SwapperNoOp::SwapArray(data,length);
00337   }
00338   template<typename T>
00339   static inline void Write(const T* data, unsigned long length,
00340     std::ostream &_os) {
00341     const unsigned int type_size = sizeof(T);
00342     assert( data ); // Can we write into pointer ?
00343     assert( length );
00344     assert( _os ); // Is stream valid ?
00345     //ByteSwap<T>::SwapRangeFromSwapCodeIntoSystem((T*)data,
00346     //  _os.GetSwapCode(), length);
00347     T swappedData = SwapperNoOp::Swap(data[0]);
00348     _os.write( reinterpret_cast<const char*>(&swappedData), type_size);
00349     for(unsigned long i=1; i<length;++i) {
00350       assert( _os );
00351       swappedData = SwapperNoOp::Swap(data[i]);
00352       _os.write( reinterpret_cast<const char*>(&swappedData), type_size );
00353     }
00354     //ByteSwap<T>::SwapRangeFromSwapCodeIntoSystem((T*)data,
00355     //  _os.GetSwapCode(), length);
00356   }
00357 };
00358 
00359 // For particular case for ASCII string
00360 // WARNING: This template explicitely instanciates a particular
00361 // EncodingImplementation THEREFORE it is required to be declared after the
00362 // EncodingImplementation is needs (doh!)
00363 #if 0
00364 template<int TVM>
00365 class Element<TVM>
00366 {
00367 public:
00368   Element(const char array[])
00369     {
00370     unsigned int i = 0;
00371     const char sep = '\\';
00372     std::string sarray = array;
00373     std::string::size_type pos1 = 0;
00374     std::string::size_type pos2 = sarray.find(sep, pos1+1);
00375     while(pos2 != std::string::npos)
00376       {
00377       Internal[i++] = sarray.substr(pos1, pos2-pos1);
00378       pos1 = pos2+1;
00379       pos2 = sarray.find(sep, pos1+1);
00380       }
00381     Internal[i] = sarray.substr(pos1, pos2-pos1);
00382     // Shouldn't we do the contrary, since we know how many separators
00383     // (and default behavior is to discard anything after the VM declared
00384     assert( GetLength()-1 == i );
00385     }
00386 
00387   unsigned long GetLength() const {
00388     return VMToLength<TVM>::Length;
00389   }
00390   // Implementation of Print is common to all Mode (ASCII/Binary)
00391   void Print(std::ostream &_os) const {
00392     _os << Internal[0]; // VM is at least garantee to be one
00393     for(int i=1; i<VMToLength<TVM>::Length; ++i)
00394       _os << "," << Internal[i];
00395     }
00396 
00397   void Read(std::istream &_is) {
00398     EncodingImplementation<VR::VRASCII>::Read(Internal, GetLength(),_is);
00399     }
00400   void Write(std::ostream &_os) const {
00401     EncodingImplementation<VR::VRASCII>::Write(Internal, GetLength(),_os);
00402     }
00403 private:
00404   typename String Internal[VMToLength<TVM>::Length];
00405 };
00406 
00407 template< int TVM>
00408 class Element<VR::PN, TVM> : public StringElement<TVM>
00409 {
00410 };
00411 #endif
00412 
00413 // Implementation for the undefined length (dynamically allocated array)
00414 template<int TVR>
00415 class Element<TVR, VM::VM1_n>
00416 {
00417 public:
00418   // This the way to prevent default initialization
00419   explicit Element() { Internal=0; Length=0; Save = false; }
00420   ~Element() {
00421     if( Save ) {
00422       delete[] Internal;
00423     }
00424     Internal = 0;
00425   }
00426 
00427   static VR  GetVR()  { return (VR::VRType)TVR; }
00428   static VM  GetVM()  { return VM::VM1_n; }
00429 
00430   // Length manipulation
00431   // SetLength should really be protected anyway...all operation
00432   // should go through SetArray
00433   unsigned long GetLength() const { return Length; }
00434   typedef typename VRToType<TVR>::Type Type;
00435 
00436   void SetLength(unsigned long len) {
00437     const unsigned int size = sizeof(Type);
00438     if( len ) {
00439       if( len > Length ) {
00440         // perform realloc
00441         assert( (len / size) * size == len );
00442         Type *internal = new Type[len / size];
00443         assert( Save == false );
00444         Save = true; // ????
00445         if( Internal )
00446           {
00447           memcpy(internal, Internal, len);
00448           delete[] Internal;
00449           }
00450         Internal = internal;
00451         }
00452       }
00453     Length = len / size;
00454   }
00455 
00456   // If save is set to zero user should not delete the pointer
00457   //void SetArray(const typename VRToType<TVR>::Type *array, int len, bool save = false)
00458   void SetArray(const Type *array, unsigned long len,
00459     bool save = false) {
00460     if( save ) {
00461       SetLength(len); // realloc
00462       memcpy(Internal, array, len/*/sizeof(Type)*/);
00463       assert( Save == false );
00464       }
00465     else {
00466       // TODO rewrite this stupid code:
00467       assert( Length == 0 );
00468       assert( Internal == 0 );
00469       assert( Save == false );
00470       Length = len / sizeof(Type);
00471       //assert( (len / sizeof(Type)) * sizeof(Type) == len );
00472       // MR00010001.dcm is a tough kid: 0019,105a is supposed to be VR::FL, VM::VM3 but
00473       // length is 14 bytes instead of 12 bytes. Simply consider value is total garbage.
00474       if( (len / sizeof(Type)) * sizeof(Type) != len ) { Internal = 0; Length = 0; }
00475       else Internal = const_cast<Type*>(array);
00476       }
00477       Save = save;
00478   }
00479   void SetValue(typename VRToType<TVR>::Type v, unsigned int idx = 0) {
00480     assert( idx < Length );
00481     Internal[idx] = v;
00482   }
00483   const typename VRToType<TVR>::Type &GetValue(unsigned int idx = 0) const {
00484     assert( idx < Length );
00485     return Internal[idx];
00486   }
00487   typename VRToType<TVR>::Type &GetValue(unsigned int idx = 0) {
00488     assert( idx < Length );
00489     return Internal[idx];
00490   }
00491   typename VRToType<TVR>::Type operator[] (unsigned int idx) const {
00492     return GetValue(idx);
00493   }
00494   void Set(Value const &v) {
00495     const ByteValue *bv = dynamic_cast<const ByteValue*>(&v);
00496     assert( bv ); // That would be bad...
00497     if( (VR::VRType)(VRToEncoding<TVR>::Mode) == VR::VRBINARY )
00498       {
00499       const Type* array = (Type*)bv->GetPointer();
00500       if( array ) {
00501         assert( array ); // That would be bad...
00502         assert( Internal == 0 );
00503         SetArray(array, bv->GetLength() ); }
00504       }
00505     else
00506       {
00507       std::stringstream ss;
00508       std::string s = std::string( bv->GetPointer(), bv->GetLength() );
00509       ss.str( s );
00510       EncodingImplementation<VRToEncoding<TVR>::Mode>::Read(Internal,
00511         GetLength(),ss);
00512       }
00513   }
00514   void SetFromDataElement(DataElement const &de) {
00515     const ByteValue *bv = de.GetByteValue();
00516     if( !bv ) return;
00517 #ifdef GDCM_WORDS_BIGENDIAN
00518     if( de.GetVR() == VR::UN /*|| de.GetVR() == VR::INVALID*/ )
00519 #else
00520     if( de.GetVR() == VR::UN || de.GetVR() == VR::INVALID )
00521 #endif
00522       {
00523       Set(de.GetValue());
00524       }
00525     else
00526       {
00527       SetNoSwap(de.GetValue());
00528       }
00529   }
00530 
00531 
00532   // Need to be placed after definition of EncodingImplementation<VR::VRASCII>
00533   void WriteASCII(std::ostream &os) const {
00534     return EncodingImplementation<VR::VRASCII>::Write(Internal, GetLength(), os);
00535     }
00536 
00537   // Implementation of Print is common to all Mode (ASCII/Binary)
00538   void Print(std::ostream &_os) const {
00539     assert( Length );
00540     assert( Internal );
00541     _os << Internal[0]; // VM is at least garantee to be one
00542     const unsigned long length = GetLength() < 25 ? GetLength() : 25;
00543     for(unsigned long i=1; i<length; ++i)
00544       _os << "," << Internal[i];
00545     }
00546   void Read(std::istream &_is) {
00547     if( !Internal ) return;
00548     EncodingImplementation<VRToEncoding<TVR>::Mode>::Read(Internal,
00549       GetLength(),_is);
00550     }
00551   //void ReadComputeLength(std::istream &_is) {
00552   //  if( !Internal ) return;
00553   //  EncodingImplementation<VRToEncoding<TVR>::Mode>::ReadComputeLength(Internal,
00554   //    Length,_is);
00555   //  }
00556   void Write(std::ostream &_os) const {
00557     EncodingImplementation<VRToEncoding<TVR>::Mode>::Write(Internal,
00558       GetLength(),_os);
00559     }
00560 
00561   DataElement GetAsDataElement() const {
00562     DataElement ret;
00563     ret.SetVR( (VR::VRType)TVR );
00564     assert( ret.GetVR() != VR::SQ );
00565     if( Internal )
00566       {
00567       std::ostringstream os;
00568       EncodingImplementation<VRToEncoding<TVR>::Mode>::Write(Internal,
00569         GetLength(),os);
00570       if( (VR::VRType)VRToEncoding<TVR>::Mode == VR::VRASCII )
00571         {
00572         if( GetVR() != VR::UI )
00573           {
00574           if( os.str().size() % 2 )
00575             {
00576             os << " ";
00577             }
00578           }
00579         }
00580       VL::Type osStrSize = (VL::Type)os.str().size();
00581       ret.SetByteValue( os.str().c_str(), osStrSize );
00582       }
00583     return ret;
00584   }
00585 
00586   Element(const Element&_val) {
00587     if( this != &_val) {
00588       *this = _val;
00589       }
00590     }
00591 
00592   Element &operator=(const Element &_val) {
00593     Length = 0; // SYITF
00594     Internal = 0;
00595     SetArray(_val.Internal, _val.Length, true);
00596     return *this;
00597     }
00598 protected:
00599   void SetNoSwap(Value const &v) {
00600     const ByteValue *bv = dynamic_cast<const ByteValue*>(&v);
00601     assert( bv ); // That would be bad...
00602     if( (VR::VRType)(VRToEncoding<TVR>::Mode) == VR::VRBINARY )
00603       {
00604       const Type* array = (Type*)bv->GetPointer();
00605       if( array ) {
00606         assert( array ); // That would be bad...
00607         assert( Internal == 0 );
00608         SetArray(array, bv->GetLength() ); }
00609       }
00610     else
00611       {
00612       std::stringstream ss;
00613       std::string s = std::string( bv->GetPointer(), bv->GetLength() );
00614       ss.str( s );
00615       EncodingImplementation<VRToEncoding<TVR>::Mode>::ReadNoSwap(Internal,
00616         GetLength(),ss);
00617       }
00618   }
00619 
00620 private:
00621   typename VRToType<TVR>::Type *Internal;
00622   unsigned long Length; // unsigned int ??
00623   bool Save;
00624 };
00625 
00626 //template <int TVM = VM::VM1_n>
00627 //class Element<VR::OB, TVM > : public Element<VR::OB, VM::VM1_n> {};
00628 
00629 // Partial specialization for derivatives of 1-n : 2-n, 3-n ...
00630 template<int TVR>
00631 class Element<TVR, VM::VM1_2> : public Element<TVR, VM::VM1_n>
00632 {
00633 public:
00634   typedef Element<TVR, VM::VM1_n> Parent;
00635   void SetLength(int len) {
00636     if( len != 1 || len != 2 ) return;
00637     Parent::SetLength(len);
00638   }
00639 };
00640 template<int TVR>
00641 class Element<TVR, VM::VM2_n> : public Element<TVR, VM::VM1_n>
00642 {
00643 public:
00644   typedef Element<TVR, VM::VM1_n> Parent;
00645   void SetLength(int len) {
00646     if( len <= 1 ) return;
00647     Parent::SetLength(len);
00648   }
00649 };
00650 template<int TVR>
00651 class Element<TVR, VM::VM2_2n> : public Element<TVR, VM::VM2_n>
00652 {
00653 public:
00654   typedef Element<TVR, VM::VM2_n> Parent;
00655   void SetLength(int len) {
00656     if( len % 2 ) return;
00657     Parent::SetLength(len);
00658   }
00659 };
00660 template<int TVR>
00661 class Element<TVR, VM::VM3_n> : public Element<TVR, VM::VM1_n>
00662 {
00663 public:
00664   typedef Element<TVR, VM::VM1_n> Parent;
00665   void SetLength(int len) {
00666     if( len <= 2 ) return;
00667     Parent::SetLength(len);
00668   }
00669 };
00670 template<int TVR>
00671 class Element<TVR, VM::VM3_3n> : public Element<TVR, VM::VM3_n>
00672 {
00673 public:
00674   typedef Element<TVR, VM::VM3_n> Parent;
00675   void SetLength(int len) {
00676     if( len % 3 ) return;
00677     Parent::SetLength(len);
00678   }
00679 };
00680 
00681 
00682 //template<int T> struct VRToLength;
00683 //template <> struct VRToLength<VR::AS>
00684 //{ enum { Length  = VM::VM1 }; }
00685 //template<>
00686 //class Element<VR::AS> : public Element<VR::AS, VRToLength<VR::AS>::Length >
00687 
00688 // only 0010 1010 AS 1 Patient's Age
00689 template<>
00690 class Element<VR::AS, VM::VM5>
00691 {
00692 public:
00693   char Internal[VMToLength<VM::VM5>::Length * sizeof( VRToType<VR::AS>::Type )];
00694   void Print(std::ostream &_os) const {
00695     _os << Internal;
00696     }
00697   unsigned long GetLength() const {
00698     return VMToLength<VM::VM5>::Length;
00699   }
00700 };
00701 
00702 template <>
00703 class Element<VR::OB, VM::VM1> : public Element<VR::OB, VM::VM1_n> {};
00704 // Make it impossible to compile any other cases:
00705 template <int TVM> class Element<VR::OB, TVM>;
00706 
00707 // Same for OW:
00708 template <>
00709 class Element<VR::OW, VM::VM1> : public Element<VR::OW, VM::VM1_n> {};
00710 // Make it impossible to compile any other cases:
00711 template <int TVM> class Element<VR::OW, TVM>;
00712 
00713 } // namespace gdcm
00714 
00715 #endif //GDCMELEMENT_H

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