GDCM 2.0.17
|
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 GDCMATTRIBUTE_H 00016 #define GDCMATTRIBUTE_H 00017 00018 #include "gdcmTypes.h" 00019 #include "gdcmVR.h" 00020 #include "gdcmTagToType.h" 00021 #include "gdcmVM.h" 00022 #include "gdcmElement.h" 00023 #include "gdcmDataElement.h" 00024 #include "gdcmDataSet.h" 00025 #include "gdcmStaticAssert.h" 00026 00027 #include <string> 00028 #include <vector> 00029 #include <sstream> 00030 00031 namespace gdcm 00032 { 00033 00034 struct void_; 00035 00036 // Declaration, also serve as forward declaration 00037 template<int T> class VRVLSize; 00038 00039 // Implementation when VL is coded on 16 bits: 00040 template<> class VRVLSize<0> { 00041 public: 00042 static inline uint16_t Read(std::istream &_is) { 00043 uint16_t l; 00044 _is.read((char*)&l, 2); 00045 return l; 00046 } 00047 00048 static inline void Write(std::ostream &os) { (void)os; 00049 } 00050 }; 00051 // Implementation when VL is coded on 32 bits: 00052 template<> class VRVLSize<1> { 00053 public: 00054 static inline uint32_t Read(std::istream &_is) { 00055 char dummy[2]; 00056 _is.read(dummy, 2); 00057 00058 uint32_t l; 00059 _is.read((char*)&l, 4); 00060 return l; 00061 } 00062 00063 static inline void Write(std::ostream &os) { (void)os; 00064 } 00065 }; 00066 00082 template<uint16_t Group, uint16_t Element, 00083 int TVR = TagToType<Group, Element>::VRType, // can the user override this value ? 00084 int TVM = TagToType<Group, Element>::VMType // can the user override this value ? 00085 /*typename SQAttribute = void_*/ > // if only I had variadic template... 00086 class Attribute 00087 { 00088 public: 00089 typedef typename VRToType<TVR>::Type ArrayType; 00090 enum { VMType = VMToLength<TVM>::Length }; 00091 ArrayType Internal[VMToLength<TVM>::Length]; 00092 00093 // Make sure that user specified VR/VM are compatible with the public dictionary: 00094 GDCM_STATIC_ASSERT( ((VR::VRType)TVR & (VR::VRType)(TagToType<Group, Element>::VRType)) ); 00095 GDCM_STATIC_ASSERT( ((VM::VMType)TVM & (VM::VMType)(TagToType<Group, Element>::VMType)) ); 00096 GDCM_STATIC_ASSERT( ((((VR::VRType)TVR & VR::VR_VM1) && ((VM::VMType)TVM == VM::VM1) ) 00097 || !((VR::VRType)TVR & VR::VR_VM1) ) ); 00098 00099 static Tag GetTag() { return Tag(Group,Element); } 00100 static VR GetVR() { return (VR::VRType)TVR; } 00101 static VM GetVM() { return (VM::VMType)TVM; } 00102 00103 // The following two methods do make sense only in case of public element, 00104 // when the template is intanciated with private element the VR/VM are simply 00105 // defaulted to allow everything (see gdcmTagToType.h default template for TagToType) 00106 static VR GetDictVR() { return (VR::VRType)(TagToType<Group, Element>::VRType); } 00107 static VM GetDictVM() { return (VM::VMType)(TagToType<Group, Element>::VMType); } 00108 00109 // Some extra dummy checks: 00110 // Data Elements with a VR of SQ, OF, OW, OB or UN shall always have a Value Multiplicity of one. 00111 00112 unsigned int GetNumberOfValues() const { 00113 return VMToLength<TVM>::Length; 00114 } 00115 // Implementation of Print is common to all Mode (ASCII/Binary) 00116 // TODO: Can we print a \ when in ASCII...well I don't think so 00117 // it would mean we used a bad VM then, right ? 00118 void Print(std::ostream &os) const { 00119 os << GetTag() << " "; 00120 os << TagToType<Group,Element>::GetVRString() << " "; 00121 os << TagToType<Group,Element>::GetVMString() << " "; 00122 os << Internal[0]; // VM is at least garantee to be one 00123 for(unsigned int i=1; i<GetNumberOfValues(); ++i) 00124 os << "," << Internal[i]; 00125 } 00126 00127 // copy: 00128 //ArrayType GetValue(unsigned int idx = 0) { 00129 // assert( idx < GetNumberOfValues() ); 00130 // return Internal[idx]; 00131 //} 00132 //ArrayType operator[] (unsigned int idx) { 00133 // return GetValue(idx); 00134 //} 00135 // FIXME: is this always a good idea ? 00136 // I do not think so, I prefer operator 00137 //operator ArrayType () const { return Internal[0]; } 00138 00139 bool operator==(const Attribute &att) const 00140 { 00141 return std::equal(Internal, Internal+GetNumberOfValues(), 00142 att.GetValues()); 00143 } 00144 bool operator!=(const Attribute &att) const 00145 { 00146 return !std::equal(Internal, Internal+GetNumberOfValues(), 00147 att.GetValues()); 00148 } 00149 bool operator<(const Attribute &att) const 00150 { 00151 return std::lexicographical_compare(Internal, Internal+GetNumberOfValues(), 00152 att.GetValues(), att.GetValues() + att.GetNumberOfValues() ); 00153 } 00154 00155 ArrayType &GetValue(unsigned int idx = 0) { 00156 assert( idx < GetNumberOfValues() ); 00157 return Internal[idx]; 00158 } 00159 ArrayType & operator[] (unsigned int idx) { 00160 return GetValue(idx); 00161 } 00162 // const reference 00163 ArrayType const &GetValue(unsigned int idx = 0) const { 00164 assert( idx < GetNumberOfValues() ); 00165 return Internal[idx]; 00166 } 00167 ArrayType const & operator[] (unsigned int idx) const { 00168 return GetValue(idx); 00169 } 00170 void SetValue(ArrayType v, unsigned int idx = 0) { 00171 assert( idx < GetNumberOfValues() ); 00172 Internal[idx] = v; 00173 } 00174 void SetValues(const ArrayType* array, unsigned int numel = VMType ) { 00175 assert( array && numel && numel == GetNumberOfValues() ); 00176 // std::copy is smarted than a memcpy, and will call memcpy when POD type 00177 std::copy(array, array+numel, Internal); 00178 } 00179 const ArrayType* GetValues() const { 00180 return Internal; 00181 } 00182 00183 // API to talk to the run-time layer: gdcm::DataElement 00184 DataElement GetAsDataElement() const { 00185 DataElement ret( GetTag() ); 00186 std::ostringstream os; 00187 // os.imbue(std::locale::classic()); // This is not required AFAIK 00188 EncodingImplementation<VRToEncoding<TVR>::Mode>::Write(Internal, 00189 GetNumberOfValues(),os); 00190 ret.SetVR( GetVR() ); 00191 assert( ret.GetVR() != VR::SQ ); 00192 if( (VR::VRType)VRToEncoding<TVR>::Mode == VR::VRASCII ) 00193 { 00194 if( GetVR() != VR::UI ) 00195 { 00196 if( os.str().size() % 2 ) 00197 { 00198 os << " "; 00199 } 00200 } 00201 } 00202 VL::Type osStrSize = (VL::Type)os.str().size(); 00203 ret.SetByteValue( os.str().c_str(), osStrSize ); 00204 return ret; 00205 } 00206 00207 void SetFromDataElement(DataElement const &de) { 00208 // This is kind of hackish but since I do not generate other element than the first one: 0x6000 I should be ok: 00209 assert( GetTag() == de.GetTag() || GetTag().GetGroup() == 0x6000 || GetTag().GetGroup() == 0x5000 ); 00210 assert( GetVR() != VR::INVALID ); 00211 assert( GetVR().Compatible( de.GetVR() ) || de.GetVR() == VR::INVALID ); // In case of VR::INVALID cannot use the & operator 00212 if( de.IsEmpty() ) return; 00213 const ByteValue *bv = de.GetByteValue(); 00214 #ifdef GDCM_WORDS_BIGENDIAN 00215 if( de.GetVR() == VR::UN /*|| de.GetVR() == VR::INVALID*/ ) 00216 #else 00217 if( de.GetVR() == VR::UN || de.GetVR() == VR::INVALID ) 00218 #endif 00219 { 00220 SetByteValue(bv); 00221 } 00222 else 00223 { 00224 SetByteValueNoSwap(bv); 00225 } 00226 } 00227 void Set(DataSet const &ds) { 00228 SetFromDataElement( ds.GetDataElement( GetTag() ) ); 00229 } 00230 void SetFromDataSet(DataSet const &ds) { 00231 if( ds.FindDataElement( GetTag() ) && 00232 !ds.GetDataElement( GetTag() ).IsEmpty() ) 00233 { 00234 SetFromDataElement( ds.GetDataElement( GetTag() ) ); 00235 } 00236 } 00237 protected: 00238 void SetByteValueNoSwap(const ByteValue *bv) { 00239 if( !bv ) return; // That would be bad... 00240 assert( bv->GetPointer() && bv->GetLength() ); // [123]C element can be empty 00241 //if( VRToEncoding<TVR>::Mode == VR::VRBINARY ) 00242 // { 00243 // // always do a copy ! 00244 // SetValues(bv->GetPointer(), bv->GetLength()); 00245 // } 00246 //else 00247 { 00248 std::stringstream ss; 00249 std::string s = std::string( bv->GetPointer(), bv->GetLength() ); 00250 ss.str( s ); 00251 EncodingImplementation<VRToEncoding<TVR>::Mode>::ReadNoSwap(Internal, 00252 GetNumberOfValues(),ss); 00253 } 00254 } 00255 void SetByteValue(const ByteValue *bv) { 00256 if( !bv ) return; // That would be bad... 00257 assert( bv->GetPointer() && bv->GetLength() ); // [123]C element can be empty 00258 //if( VRToEncoding<TVR>::Mode == VR::VRBINARY ) 00259 // { 00260 // // always do a copy ! 00261 // SetValues(bv->GetPointer(), bv->GetLength()); 00262 // } 00263 //else 00264 { 00265 std::stringstream ss; 00266 std::string s = std::string( bv->GetPointer(), bv->GetLength() ); 00267 ss.str( s ); 00268 EncodingImplementation<VRToEncoding<TVR>::Mode>::Read(Internal, 00269 GetNumberOfValues(),ss); 00270 } 00271 } 00272 #if 0 // TODO FIXME the implicit way: 00273 // explicit: 00274 void Read(std::istream &_is) { 00275 const uint16_t cref[] = { Group, Element }; 00276 uint16_t c[2]; 00277 _is.read((char*)&c, sizeof(c)); 00278 assert( c[0] == cref[0] && c[1] == cref[1] ); 00279 char vr[2]; 00280 _is.read(vr, 2); // Check consistency ? 00281 const uint32_t lref = GetLength() * sizeof( typename VRToType<TVR>::Type ); 00282 uint32_t l = VRVLSize< (TVR & VR::VL32) >::Read(_is); 00283 l /= sizeof( typename VRToType<TVR>::Type ); 00284 return EncodingImplementation<VRToEncoding<TVR>::Mode>::Read(Internal, 00285 l,_is); 00286 } 00287 void Write(std::ostream &_os) const { 00288 uint16_t c[] = { Group, Element }; 00289 _os.write((char*)&c, 4); 00290 uint32_t l = GetLength() * sizeof( typename VRToType<TVR>::Type ); 00291 _os.write((char*)&l, 4); 00292 return EncodingImplementation<VRToEncoding<TVR>::Mode>::Write(Internal, 00293 GetLength(),_os); 00294 } 00295 void Read(std::istream &_is) { 00296 uint16_t cref[] = { Group, Element }; 00297 uint16_t c[2]; 00298 _is.read((char*)&c, 4); 00299 const uint32_t lref = GetLength() * sizeof( typename VRToType<TVR>::Type ); 00300 uint32_t l; 00301 _is.read((char*)&l, 4); 00302 l /= sizeof( typename VRToType<TVR>::Type ); 00303 return EncodingImplementation<VRToEncoding<TVR>::Mode>::Read(Internal, 00304 l,_is); 00305 } 00306 void Write(std::ostream &_os) const { 00307 uint16_t c[] = { Group, Element }; 00308 _os.write((char*)&c, 4); 00309 uint32_t l = GetLength() * sizeof( typename VRToType<TVR>::Type ); 00310 _os.write((char*)&l, 4); 00311 return EncodingImplementation<VRToEncoding<TVR>::Mode>::Write(Internal, 00312 GetLength(),_os); 00313 } 00314 #endif 00315 00316 }; 00317 00318 template<uint16_t Group, uint16_t Element, int TVR > 00319 class Attribute<Group,Element,TVR,VM::VM1> 00320 { 00321 public: 00322 typedef typename VRToType<TVR>::Type ArrayType; 00323 enum { VMType = VMToLength<VM::VM1>::Length }; 00324 //ArrayType Internal[VMToLength<TVM>::Length]; 00325 ArrayType Internal; 00326 GDCM_STATIC_ASSERT( VMToLength<VM::VM1>::Length == 1 ); 00327 00328 // Make sure that user specified VR/VM are compatible with the public dictionary: 00329 GDCM_STATIC_ASSERT( ((VR::VRType)TVR & (VR::VRType)(TagToType<Group, Element>::VRType)) ); 00330 GDCM_STATIC_ASSERT( ((VM::VMType)VM::VM1 & (VM::VMType)(TagToType<Group, Element>::VMType)) ); 00331 GDCM_STATIC_ASSERT( ((((VR::VRType)TVR & VR::VR_VM1) && ((VM::VMType)VM::VM1 == VM::VM1) ) 00332 || !((VR::VRType)TVR & VR::VR_VM1) ) ); 00333 00334 static Tag GetTag() { return Tag(Group,Element); } 00335 static VR GetVR() { return (VR::VRType)TVR; } 00336 static VM GetVM() { return (VM::VMType)VM::VM1; } 00337 00338 // The following two methods do make sense only in case of public element, 00339 // when the template is intanciated with private element the VR/VM are simply 00340 // defaulted to allow everything (see gdcmTagToType.h default template for TagToType) 00341 static VR GetDictVR() { return (VR::VRType)(TagToType<Group, Element>::VRType); } 00342 static VM GetDictVM() { return (VM::VMType)(TagToType<Group, Element>::VMType); } 00343 00344 // Some extra dummy checks: 00345 // Data Elements with a VR of SQ, OF, OW, OB or UN shall always have a Value Multiplicity of one. 00346 00347 unsigned int GetNumberOfValues() const { 00348 return VMToLength<VM::VM1>::Length; 00349 } 00350 // Implementation of Print is common to all Mode (ASCII/Binary) 00351 // TODO: Can we print a \ when in ASCII...well I don't think so 00352 // it would mean we used a bad VM then, right ? 00353 void Print(std::ostream &os) const { 00354 os << GetTag() << " "; 00355 os << TagToType<Group,Element>::GetVRString() << " "; 00356 os << TagToType<Group,Element>::GetVMString() << " "; 00357 os << Internal; // VM is at least garantee to be one 00358 } 00359 // copy: 00360 //ArrayType GetValue(unsigned int idx = 0) { 00361 // assert( idx < GetNumberOfValues() ); 00362 // return Internal[idx]; 00363 //} 00364 //ArrayType operator[] (unsigned int idx) { 00365 // return GetValue(idx); 00366 //} 00367 // FIXME: is this always a good idea ? 00368 // I do not think so, I prefer operator 00369 //operator ArrayType () const { return Internal[0]; } 00370 00371 bool operator==(const Attribute &att) const 00372 { 00373 return std::equal(&Internal, &Internal+GetNumberOfValues(), 00374 att.GetValues()); 00375 } 00376 bool operator!=(const Attribute &att) const 00377 { 00378 return !std::equal(&Internal, &Internal+GetNumberOfValues(), 00379 att.GetValues()); 00380 } 00381 bool operator<(const Attribute &att) const 00382 { 00383 return std::lexicographical_compare(&Internal, &Internal+GetNumberOfValues(), 00384 att.GetValues(), att.GetValues() + att.GetNumberOfValues() ); 00385 } 00386 00387 ArrayType &GetValue() { 00388 // assert( idx < GetNumberOfValues() ); 00389 return Internal; 00390 } 00391 // ArrayType & operator[] (unsigned int idx) { 00392 // return GetValue(idx); 00393 // } 00394 // const reference 00395 ArrayType const &GetValue() const { 00396 //assert( idx < GetNumberOfValues() ); 00397 return Internal; 00398 } 00399 //ArrayType const & operator[] () const { 00400 // return GetValue(); 00401 //} 00402 void SetValue(ArrayType v) { 00403 // assert( idx < GetNumberOfValues() ); 00404 Internal = v; 00405 } 00406 /* void SetValues(const ArrayType* array, unsigned int numel = VMType ) { 00407 assert( array && numel && numel == GetNumberOfValues() ); 00408 // std::copy is smarted than a memcpy, and will call memcpy when POD type 00409 std::copy(array, array+numel, Internal); 00410 } 00411 */ 00412 00413 // FIXME Should we remove this function ? 00414 const ArrayType* GetValues() const { 00415 return &Internal; 00416 } 00417 00418 // API to talk to the run-time layer: gdcm::DataElement 00419 DataElement GetAsDataElement() const { 00420 DataElement ret( GetTag() ); 00421 std::ostringstream os; 00422 // os.imbue(std::locale::classic()); // This is not required AFAIK 00423 EncodingImplementation<VRToEncoding<TVR>::Mode>::Write(&Internal, 00424 GetNumberOfValues(),os); 00425 ret.SetVR( GetVR() ); 00426 assert( ret.GetVR() != VR::SQ ); 00427 if( (VR::VRType)VRToEncoding<TVR>::Mode == VR::VRASCII ) 00428 { 00429 if( GetVR() != VR::UI ) 00430 { 00431 if( os.str().size() % 2 ) 00432 { 00433 os << " "; 00434 } 00435 } 00436 } 00437 VL::Type osStrSize = (VL::Type)os.str().size(); 00438 ret.SetByteValue( os.str().c_str(), osStrSize ); 00439 return ret; 00440 } 00441 00442 void SetFromDataElement(DataElement const &de) { 00443 // This is kind of hackish but since I do not generate other element than the first one: 0x6000 I should be ok: 00444 assert( GetTag() == de.GetTag() || GetTag().GetGroup() == 0x6000 || GetTag().GetGroup() == 0x5000 ); 00445 assert( GetVR() != VR::INVALID ); 00446 assert( GetVR().Compatible( de.GetVR() ) || de.GetVR() == VR::INVALID ); // In case of VR::INVALID cannot use the & operator 00447 if( de.IsEmpty() ) return; 00448 const ByteValue *bv = de.GetByteValue(); 00449 if( de.GetVR() == VR::UN || de.GetVR() == VR::INVALID ) 00450 { 00451 SetByteValue(bv); 00452 } 00453 else 00454 { 00455 SetByteValueNoSwap(bv); 00456 } 00457 } 00458 void Set(DataSet const &ds) { 00459 SetFromDataElement( ds.GetDataElement( GetTag() ) ); 00460 } 00461 void SetFromDataSet(DataSet const &ds) { 00462 if( ds.FindDataElement( GetTag() ) && 00463 !ds.GetDataElement( GetTag() ).IsEmpty() ) 00464 { 00465 SetFromDataElement( ds.GetDataElement( GetTag() ) ); 00466 } 00467 } 00468 protected: 00469 void SetByteValueNoSwap(const ByteValue *bv) { 00470 if( !bv ) return; // That would be bad... 00471 assert( bv->GetPointer() && bv->GetLength() ); // [123]C element can be empty 00472 //if( VRToEncoding<TVR>::Mode == VR::VRBINARY ) 00473 // { 00474 // // always do a copy ! 00475 // SetValues(bv->GetPointer(), bv->GetLength()); 00476 // } 00477 //else 00478 { 00479 std::stringstream ss; 00480 std::string s = std::string( bv->GetPointer(), bv->GetLength() ); 00481 ss.str( s ); 00482 EncodingImplementation<VRToEncoding<TVR>::Mode>::ReadNoSwap(&Internal, 00483 GetNumberOfValues(),ss); 00484 } 00485 } 00486 void SetByteValue(const ByteValue *bv) { 00487 if( !bv ) return; // That would be bad... 00488 assert( bv->GetPointer() && bv->GetLength() ); // [123]C element can be empty 00489 //if( VRToEncoding<TVR>::Mode == VR::VRBINARY ) 00490 // { 00491 // // always do a copy ! 00492 // SetValues(bv->GetPointer(), bv->GetLength()); 00493 // } 00494 //else 00495 { 00496 std::stringstream ss; 00497 std::string s = std::string( bv->GetPointer(), bv->GetLength() ); 00498 ss.str( s ); 00499 EncodingImplementation<VRToEncoding<TVR>::Mode>::Read(&Internal, 00500 GetNumberOfValues(),ss); 00501 } 00502 } 00503 #if 0 // TODO FIXME the implicit way: 00504 // explicit: 00505 void Read(std::istream &_is) { 00506 const uint16_t cref[] = { Group, Element }; 00507 uint16_t c[2]; 00508 _is.read((char*)&c, sizeof(c)); 00509 assert( c[0] == cref[0] && c[1] == cref[1] ); 00510 char vr[2]; 00511 _is.read(vr, 2); // Check consistency ? 00512 const uint32_t lref = GetLength() * sizeof( typename VRToType<TVR>::Type ); 00513 uint32_t l = VRVLSize< (TVR & VR::VL32) >::Read(_is); 00514 l /= sizeof( typename VRToType<TVR>::Type ); 00515 return EncodingImplementation<VRToEncoding<TVR>::Mode>::Read(Internal, 00516 l,_is); 00517 } 00518 void Write(std::ostream &_os) const { 00519 uint16_t c[] = { Group, Element }; 00520 _os.write((char*)&c, 4); 00521 uint32_t l = GetLength() * sizeof( typename VRToType<TVR>::Type ); 00522 _os.write((char*)&l, 4); 00523 return EncodingImplementation<VRToEncoding<TVR>::Mode>::Write(Internal, 00524 GetLength(),_os); 00525 } 00526 void Read(std::istream &_is) { 00527 uint16_t cref[] = { Group, Element }; 00528 uint16_t c[2]; 00529 _is.read((char*)&c, 4); 00530 const uint32_t lref = GetLength() * sizeof( typename VRToType<TVR>::Type ); 00531 uint32_t l; 00532 _is.read((char*)&l, 4); 00533 l /= sizeof( typename VRToType<TVR>::Type ); 00534 return EncodingImplementation<VRToEncoding<TVR>::Mode>::Read(Internal, 00535 l,_is); 00536 } 00537 void Write(std::ostream &_os) const { 00538 uint16_t c[] = { Group, Element }; 00539 _os.write((char*)&c, 4); 00540 uint32_t l = GetLength() * sizeof( typename VRToType<TVR>::Type ); 00541 _os.write((char*)&l, 4); 00542 return EncodingImplementation<VRToEncoding<TVR>::Mode>::Write(Internal, 00543 GetLength(),_os); 00544 } 00545 #endif 00546 00547 }; 00548 00549 // No need to repeat default template arg, since primary template 00550 // will be used to generate the default arguments 00551 template<uint16_t Group, uint16_t Element, int TVR > 00552 class Attribute<Group,Element,TVR,VM::VM1_n> 00553 { 00554 public: 00555 typedef typename VRToType<TVR>::Type ArrayType; 00556 00557 // Make sure that user specified VR/VM are compatible with the public dictionary: 00558 GDCM_STATIC_ASSERT( ((VR::VRType)TVR & (VR::VRType)(TagToType<Group, Element>::VRType)) ); 00559 GDCM_STATIC_ASSERT( (VM::VM1_n & (VM::VMType)(TagToType<Group, Element>::VMType)) ); 00560 GDCM_STATIC_ASSERT( ((((VR::VRType)TVR & VR::VR_VM1) && ((VM::VMType)TagToType<Group,Element>::VMType == VM::VM1) ) 00561 || !((VR::VRType)TVR & VR::VR_VM1) ) ); 00562 00563 static Tag GetTag() { return Tag(Group,Element); } 00564 static VR GetVR() { return (VR::VRType)TVR; } 00565 static VM GetVM() { return VM::VM1_n; } 00566 00567 static VR GetDictVR() { return (VR::VRType)(TagToType<Group, Element>::VRType); } 00568 static VM GetDictVM() { return GetVM(); } 00569 00570 // This the way to prevent default initialization 00571 explicit Attribute() { Internal=0; Length=0; Own = true; } 00572 ~Attribute() { 00573 if( Own ) { 00574 delete[] Internal; 00575 } 00576 Internal = 0; // paranoid 00577 } 00578 00579 unsigned int GetNumberOfValues() const { return Length; } 00580 00581 void SetNumberOfValues(unsigned int numel) 00582 { 00583 SetValues(NULL, numel, true); 00584 } 00585 00586 const ArrayType* GetValues() const { 00587 return Internal; 00588 } 00589 void Print(std::ostream &os) const { 00590 os << GetTag() << " "; 00591 os << GetVR() << " "; 00592 os << GetVM() << " "; 00593 os << Internal[0]; // VM is at least garantee to be one 00594 for(unsigned int i=1; i<GetNumberOfValues(); ++i) 00595 os << "," << Internal[i]; 00596 } 00597 ArrayType &GetValue(unsigned int idx = 0) { 00598 assert( idx < GetNumberOfValues() ); 00599 return Internal[idx]; 00600 } 00601 ArrayType &operator[] (unsigned int idx) { 00602 return GetValue(idx); 00603 } 00604 // const reference 00605 ArrayType const &GetValue(unsigned int idx = 0) const { 00606 assert( idx < GetNumberOfValues() ); 00607 return Internal[idx]; 00608 } 00609 ArrayType const & operator[] (unsigned int idx) const { 00610 return GetValue(idx); 00611 } 00612 void SetValue(unsigned int idx, ArrayType v) { 00613 assert( idx < GetNumberOfValues() ); 00614 Internal[idx] = v; 00615 } 00616 void SetValue(ArrayType v) { SetValue(0, v); } 00617 00618 void SetValues(const ArrayType *array, unsigned int numel, bool own = false) 00619 { 00620 if( Internal ) // were we used before ? 00621 { 00622 // yes ! 00623 if( Own ) delete[] Internal; 00624 Internal = 0; 00625 } 00626 Own = own; 00627 Length = numel; 00628 assert( Internal == 0 ); 00629 if( own ) // make a copy: 00630 { 00631 assert( /*array &&*/ numel ); 00632 Internal = new ArrayType[numel]; 00633 if( array && numel ) 00634 std::copy(array, array+numel, Internal); 00635 } 00636 else // pass pointer 00637 { 00638 Internal = const_cast<ArrayType*>(array); 00639 } 00640 // postcondition 00641 assert( numel == GetNumberOfValues() ); 00642 } 00643 00644 DataElement GetAsDataElement() const { 00645 DataElement ret( GetTag() ); 00646 std::ostringstream os; 00647 if( Internal ) 00648 { 00649 EncodingImplementation<VRToEncoding<TVR>::Mode>::Write(Internal, 00650 GetNumberOfValues(),os); 00651 if( (VR::VRType)VRToEncoding<TVR>::Mode == VR::VRASCII ) 00652 { 00653 if( GetVR() != VR::UI ) 00654 { 00655 if( os.str().size() % 2 ) 00656 { 00657 os << " "; 00658 } 00659 } 00660 } 00661 } 00662 ret.SetVR( GetVR() ); 00663 assert( ret.GetVR() != VR::SQ ); 00664 VL::Type osStrSize = (VL::Type) os.str().size(); 00665 ret.SetByteValue( os.str().c_str(), osStrSize); 00666 return ret; 00667 } 00668 void SetFromDataElement(DataElement const &de) { 00669 // This is kind of hackish but since I do not generate other element than the first one: 0x6000 I should be ok: 00670 assert( GetTag() == de.GetTag() || GetTag().GetGroup() == 0x6000 ); 00671 assert( GetVR().Compatible( de.GetVR() ) ); // In case of VR::INVALID cannot use the & operator 00672 assert( !de.IsEmpty() ); 00673 const ByteValue *bv = de.GetByteValue(); 00674 SetByteValue(bv); 00675 } 00676 protected: 00677 void SetByteValue(const ByteValue *bv) { 00678 assert( bv ); // FIXME 00679 std::stringstream ss; 00680 std::string s = std::string( bv->GetPointer(), bv->GetLength() ); 00681 Length = bv->GetLength(); // HACK FIXME 00682 ss.str( s ); 00683 ArrayType *internal; 00684 ArrayType buffer[256]; 00685 if( bv->GetLength() < 256 ) 00686 { 00687 internal = buffer; 00688 } 00689 else 00690 { 00691 internal = new ArrayType[(VL::Type)bv->GetLength()]; // over allocation 00692 } 00693 EncodingImplementation<VRToEncoding<TVR>::Mode>::ReadComputeLength(internal, Length, ss); 00694 SetValues( internal, Length, true ); 00695 if( !(bv->GetLength() < 256) ) 00696 { 00697 delete[] internal; 00698 } 00699 //EncodingImplementation<VRToEncoding<TVR>::Mode>::Read(Internal, 00700 // GetNumberOfValues(),ss); 00701 } 00702 00703 private: 00704 ArrayType *Internal; 00705 unsigned int Length; 00706 bool Own : 1; 00707 }; 00708 00709 template<uint16_t Group, uint16_t Element, int TVR> 00710 class Attribute<Group,Element,TVR,VM::VM1_8> : public Attribute<Group,Element,TVR,VM::VM1_n> 00711 { 00712 public: 00713 VM GetVM() const { return VM::VM1_8; } 00714 }; 00715 00716 template<uint16_t Group, uint16_t Element, int TVR> 00717 class Attribute<Group,Element,TVR,VM::VM2_n> : public Attribute<Group,Element,TVR,VM::VM1_n> 00718 { 00719 public: 00720 VM GetVM() const { return VM::VM2_n; } 00721 }; 00722 00723 template<uint16_t Group, uint16_t Element, int TVR> 00724 class Attribute<Group,Element,TVR,VM::VM2_2n> : public Attribute<Group,Element,TVR,VM::VM2_n> 00725 { 00726 public: 00727 static VM GetVM() { return VM::VM2_2n; } 00728 }; 00729 00730 template<uint16_t Group, uint16_t Element, int TVR> 00731 class Attribute<Group,Element,TVR,VM::VM3_n> : public Attribute<Group,Element,TVR,VM::VM1_n> 00732 { 00733 public: 00734 static VM GetVM() { return VM::VM3_n; } 00735 }; 00736 00737 template<uint16_t Group, uint16_t Element, int TVR> 00738 class Attribute<Group,Element,TVR,VM::VM3_3n> : public Attribute<Group,Element,TVR,VM::VM3_n> 00739 { 00740 public: 00741 static VM GetVM() { return VM::VM3_3n; } 00742 }; 00743 00744 00745 // For particular case for ASCII string 00746 // WARNING: This template explicitely instanciates a particular 00747 // EncodingImplementation THEREFORE it is required to be declared after the 00748 // EncodingImplementation is needs (doh!) 00749 #if 0 00750 template<int TVM> 00751 class Attribute<TVM> 00752 { 00753 public: 00754 Attribute(const char array[]) 00755 { 00756 unsigned int i = 0; 00757 const char sep = '\\'; 00758 std::string sarray = array; 00759 std::string::size_type pos1 = 0; 00760 std::string::size_type pos2 = sarray.find(sep, pos1+1); 00761 while(pos2 != std::string::npos) 00762 { 00763 Internal[i++] = sarray.substr(pos1, pos2-pos1); 00764 pos1 = pos2+1; 00765 pos2 = sarray.find(sep, pos1+1); 00766 } 00767 Internal[i] = sarray.substr(pos1, pos2-pos1); 00768 // Shouldn't we do the contrary, since we know how many separators 00769 // (and default behavior is to discard anything after the VM declared 00770 assert( GetLength()-1 == i ); 00771 } 00772 00773 unsigned long GetLength() const { 00774 return VMToLength<TVM>::Length; 00775 } 00776 // Implementation of Print is common to all Mode (ASCII/Binary) 00777 void Print(std::ostream &_os) const { 00778 _os << Internal[0]; // VM is at least garantee to be one 00779 for(int i=1; i<VMToLength<TVM>::Length; ++i) 00780 _os << "," << Internal[i]; 00781 } 00782 00783 void Read(std::istream &_is) { 00784 EncodingImplementation<VR::VRASCII>::Read(Internal, GetLength(),_is); 00785 } 00786 void Write(std::ostream &_os) const { 00787 EncodingImplementation<VR::VRASCII>::Write(Internal, GetLength(),_os); 00788 } 00789 private: 00790 typename String Internal[VMToLength<TVM>::Length]; 00791 }; 00792 00793 template< int TVM> 00794 class Attribute<VR::PN, TVM> : public StringAttribute<TVM> 00795 { 00796 }; 00797 #endif 00798 00799 #if 0 00800 00801 // Implementation for the undefined length (dynamically allocated array) 00802 template<int TVR> 00803 class Attribute<TVR, VM::VM1_n> 00804 { 00805 public: 00806 // This the way to prevent default initialization 00807 explicit Attribute() { Internal=0; Length=0; } 00808 ~Attribute() { 00809 delete[] Internal; 00810 Internal = 0; 00811 } 00812 00813 // Length manipulation 00814 // SetLength should really be protected anyway...all operation 00815 // should go through SetArray 00816 unsigned long GetLength() const { return Length; } 00817 typedef typename VRToType<TVR>::Type ArrayType; 00818 void SetLength(unsigned long len) { 00819 const unsigned int size = sizeof(ArrayType); 00820 if( len ) { 00821 if( len > Length ) { 00822 // perform realloc 00823 assert( (len / size) * size == len ); 00824 ArrayType *internal = new ArrayType[len / size]; 00825 memcpy(internal, Internal, Length * size); 00826 delete[] Internal; 00827 Internal = internal; 00828 } 00829 } 00830 Length = len / size; 00831 } 00832 00833 // If save is set to zero user should not delete the pointer 00834 //void SetArray(const typename VRToType<TVR>::Type *array, int len, bool save = false) 00835 void SetArray(const ArrayType *array, unsigned long len, 00836 bool save = false) { 00837 if( save ) { 00838 SetLength(len); // realloc 00839 memcpy(Internal, array, len/*/sizeof(ArrayType)*/); 00840 } 00841 else { 00842 // TODO rewrite this stupid code: 00843 Length = len; 00844 //Internal = array; 00845 assert(0); 00846 } 00847 } 00848 // Implementation of Print is common to all Mode (ASCII/Binary) 00849 void Print(std::ostream &_os) const { 00850 assert( Length ); 00851 assert( Internal ); 00852 _os << Internal[0]; // VM is at least garantee to be one 00853 const unsigned long length = GetLength() < 25 ? GetLength() : 25; 00854 for(unsigned long i=1; i<length; ++i) 00855 _os << "," << Internal[i]; 00856 } 00857 void Read(std::istream &_is) { 00858 EncodingImplementation<VRToEncoding<TVR>::Mode>::Read(Internal, 00859 GetLength(),_is); 00860 } 00861 void Write(std::ostream &_os) const { 00862 EncodingImplementation<VRToEncoding<TVR>::Mode>::Write(Internal, 00863 GetLength(),_os); 00864 } 00865 00866 Attribute(const Attribute&_val) { 00867 if( this != &_val) { 00868 *this = _val; 00869 } 00870 } 00871 00872 Attribute &operator=(const Attribute &_val) { 00873 Length = 0; // SYITF 00874 Internal = 0; 00875 SetArray(_val.Internal, _val.Length, true); 00876 return *this; 00877 } 00878 00879 private: 00880 typename VRToType<TVR>::Type *Internal; 00881 unsigned long Length; // unsigned int ?? 00882 }; 00883 00884 //template <int TVM = VM::VM1_n> 00885 //class Attribute<VR::OB, TVM > : public Attribute<VR::OB, VM::VM1_n> {}; 00886 00887 // Partial specialization for derivatives of 1-n : 2-n, 3-n ... 00888 template<int TVR> 00889 class Attribute<TVR, VM::VM2_n> : public Attribute<TVR, VM::VM1_n> 00890 { 00891 public: 00892 typedef Attribute<TVR, VM::VM1_n> Parent; 00893 void SetLength(int len) { 00894 if( len <= 1 ) return; 00895 Parent::SetLength(len); 00896 } 00897 }; 00898 template<int TVR> 00899 class Attribute<TVR, VM::VM2_2n> : public Attribute<TVR, VM::VM2_n> 00900 { 00901 public: 00902 typedef Attribute<TVR, VM::VM2_n> Parent; 00903 void SetLength(int len) { 00904 if( len % 2 ) return; 00905 Parent::SetLength(len); 00906 } 00907 }; 00908 template<int TVR> 00909 class Attribute<TVR, VM::VM3_n> : public Attribute<TVR, VM::VM1_n> 00910 { 00911 public: 00912 typedef Attribute<TVR, VM::VM1_n> Parent; 00913 void SetLength(int len) { 00914 if( len <= 2 ) return; 00915 Parent::SetLength(len); 00916 } 00917 }; 00918 template<int TVR> 00919 class Attribute<TVR, VM::VM3_3n> : public Attribute<TVR, VM::VM3_n> 00920 { 00921 public: 00922 typedef Attribute<TVR, VM::VM3_n> Parent; 00923 void SetLength(int len) { 00924 if( len % 3 ) return; 00925 Parent::SetLength(len); 00926 } 00927 }; 00928 00929 00930 //template<int T> struct VRToLength; 00931 //template <> struct VRToLength<VR::AS> 00932 //{ enum { Length = VM::VM1 }; } 00933 //template<> 00934 //class Attribute<VR::AS> : public Attribute<VR::AS, VRToLength<VR::AS>::Length > 00935 00936 // only 0010 1010 AS 1 Patient’s Age 00937 template<> 00938 class Attribute<VR::AS, VM::VM5> 00939 { 00940 public: 00941 char Internal[VMToLength<VM::VM5>::Length]; 00942 void Print(std::ostream &_os) const { 00943 _os << Internal; 00944 } 00945 }; 00946 00947 template <> 00948 class Attribute<VR::OB, VM::VM1> : public Attribute<VR::OB, VM::VM1_n> {}; 00949 // Make it impossible to compile any other cases: 00950 template <int TVM> class Attribute<VR::OB, TVM>; 00951 00952 // Same for OW: 00953 template <> 00954 class Attribute<VR::OW, VM::VM1> : public Attribute<VR::OW, VM::VM1_n> {}; 00955 // Make it impossible to compile any other cases: 00956 template <int TVM> class Attribute<VR::OW, TVM>; 00957 #endif 00958 00959 #if 0 00960 template<> 00961 class Attribute<0x7fe0,0x0010, VR::OW, VM::VM1> 00962 { 00963 public: 00964 char *Internal; 00965 unsigned long Length; // unsigned int ?? 00966 00967 void Print(std::ostream &_os) const { 00968 _os << Internal[0]; 00969 } 00970 void SetBytes(char *bytes, unsigned long length) { 00971 Internal = bytes; 00972 Length = length; 00973 } 00974 void Read(std::istream &_is) { 00975 uint16_t c[2]; 00976 _is.read((char*)&c, 4); 00977 uint32_t l; 00978 _is.read((char*)&l, 4); 00979 Length = l; 00980 _is.read( Internal, Length ); 00981 } 00982 void Write(std::ostream &_os) const { 00983 uint16_t c[] = {0x7fe0, 0x0010}; 00984 _os.write((char*)&c, 4); 00985 _os.write((char*)&Length, 4); 00986 _os.write( Internal, Length ); 00987 } 00988 }; 00989 #endif 00990 00991 /* 00992 // Removing Attribute for SQ for now... 00993 template<uint16_t Group, uint16_t Element, typename SQA> 00994 class Attribute<Group,Element, VR::SQ, VM::VM1, SQA> 00995 { 00996 public: 00997 SQA sqa; 00998 void Print(std::ostream &_os) const { 00999 _os << Tag(Group,Element); 01000 sqa.Print(_os << std::endl << '\t'); 01001 } 01002 void Write(std::ostream &_os) const { 01003 uint16_t c[] = {Group, Element}; 01004 _os.write((char*)&c, 4); 01005 uint32_t undef = 0xffffffff; 01006 _os.write((char*)&undef, 4); 01007 uint16_t item_beg[] = {0xfffe,0xe000}; 01008 _os.write((char*)&item_beg, 4); 01009 _os.write((char*)&undef, 4); 01010 sqa.Write(_os); 01011 uint16_t item_end[] = {0xfffe,0xe00d}; 01012 _os.write((char*)&item_end, 4); 01013 uint32_t zero = 0x0; 01014 _os.write((char*)&zero, 4); 01015 uint16_t seq_end[] = {0xfffe, 0xe0dd}; 01016 _os.write((char*)&seq_end, 4); 01017 _os.write((char*)&zero, 4); 01018 } 01019 }; 01020 */ 01021 01027 } // namespace gdcm 01028 01029 #endif //GDCMATTRIBUTE_H