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