GDCM 2.2.0

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

- File List
- File Members

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