GDCM
2.2.0
|
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 assert( GetVR().Compatible( de.GetVR() ) ); // In case of VR::INVALID cannot use the & operator 00675 assert( !de.IsEmpty() ); 00676 const ByteValue *bv = de.GetByteValue(); 00677 SetByteValue(bv); 00678 } 00679 protected: 00680 void SetByteValue(const ByteValue *bv) { 00681 assert( bv ); // FIXME 00682 std::stringstream ss; 00683 std::string s = std::string( bv->GetPointer(), bv->GetLength() ); 00684 Length = bv->GetLength(); // HACK FIXME 00685 ss.str( s ); 00686 ArrayType *internal; 00687 ArrayType buffer[256]; 00688 if( bv->GetLength() < 256 ) 00689 { 00690 internal = buffer; 00691 } 00692 else 00693 { 00694 internal = new ArrayType[(VL::Type)bv->GetLength()]; // over allocation 00695 } 00696 EncodingImplementation<VRToEncoding<TVR>::Mode>::ReadComputeLength(internal, Length, ss); 00697 SetValues( internal, Length, true ); 00698 if( !(bv->GetLength() < 256) ) 00699 { 00700 delete[] internal; 00701 } 00702 //EncodingImplementation<VRToEncoding<TVR>::Mode>::Read(Internal, 00703 // GetNumberOfValues(),ss); 00704 } 00705 00706 private: 00707 ArrayType *Internal; 00708 unsigned int Length; 00709 bool Own : 1; 00710 }; 00711 00712 template<uint16_t Group, uint16_t Element, int TVR> 00713 class Attribute<Group,Element,TVR,VM::VM1_3> : public Attribute<Group,Element,TVR,VM::VM1_n> 00714 { 00715 public: 00716 VM GetVM() const { return VM::VM1_3; } 00717 }; 00718 00719 template<uint16_t Group, uint16_t Element, int TVR> 00720 class Attribute<Group,Element,TVR,VM::VM1_8> : public Attribute<Group,Element,TVR,VM::VM1_n> 00721 { 00722 public: 00723 VM GetVM() const { return VM::VM1_8; } 00724 }; 00725 00726 template<uint16_t Group, uint16_t Element, int TVR> 00727 class Attribute<Group,Element,TVR,VM::VM2_n> : public Attribute<Group,Element,TVR,VM::VM1_n> 00728 { 00729 public: 00730 VM GetVM() const { return VM::VM2_n; } 00731 }; 00732 00733 template<uint16_t Group, uint16_t Element, int TVR> 00734 class Attribute<Group,Element,TVR,VM::VM2_2n> : public Attribute<Group,Element,TVR,VM::VM2_n> 00735 { 00736 public: 00737 static VM GetVM() { return VM::VM2_2n; } 00738 }; 00739 00740 template<uint16_t Group, uint16_t Element, int TVR> 00741 class Attribute<Group,Element,TVR,VM::VM3_n> : public Attribute<Group,Element,TVR,VM::VM1_n> 00742 { 00743 public: 00744 static VM GetVM() { return VM::VM3_n; } 00745 }; 00746 00747 template<uint16_t Group, uint16_t Element, int TVR> 00748 class Attribute<Group,Element,TVR,VM::VM3_3n> : public Attribute<Group,Element,TVR,VM::VM3_n> 00749 { 00750 public: 00751 static VM GetVM() { return VM::VM3_3n; } 00752 }; 00753 00754 00755 // For particular case for ASCII string 00756 // WARNING: This template explicitely instanciates a particular 00757 // EncodingImplementation THEREFORE it is required to be declared after the 00758 // EncodingImplementation is needs (doh!) 00759 #if 0 00760 template<int TVM> 00761 class Attribute<TVM> 00762 { 00763 public: 00764 Attribute(const char array[]) 00765 { 00766 unsigned int i = 0; 00767 const char sep = '\\'; 00768 std::string sarray = array; 00769 std::string::size_type pos1 = 0; 00770 std::string::size_type pos2 = sarray.find(sep, pos1+1); 00771 while(pos2 != std::string::npos) 00772 { 00773 Internal[i++] = sarray.substr(pos1, pos2-pos1); 00774 pos1 = pos2+1; 00775 pos2 = sarray.find(sep, pos1+1); 00776 } 00777 Internal[i] = sarray.substr(pos1, pos2-pos1); 00778 // Shouldn't we do the contrary, since we know how many separators 00779 // (and default behavior is to discard anything after the VM declared 00780 assert( GetLength()-1 == i ); 00781 } 00782 00783 unsigned long GetLength() const { 00784 return VMToLength<TVM>::Length; 00785 } 00786 // Implementation of Print is common to all Mode (ASCII/Binary) 00787 void Print(std::ostream &_os) const { 00788 _os << Internal[0]; // VM is at least garantee to be one 00789 for(int i=1; i<VMToLength<TVM>::Length; ++i) 00790 _os << "," << Internal[i]; 00791 } 00792 00793 void Read(std::istream &_is) { 00794 EncodingImplementation<VR::VRASCII>::Read(Internal, GetLength(),_is); 00795 } 00796 void Write(std::ostream &_os) const { 00797 EncodingImplementation<VR::VRASCII>::Write(Internal, GetLength(),_os); 00798 } 00799 private: 00800 typename String Internal[VMToLength<TVM>::Length]; 00801 }; 00802 00803 template< int TVM> 00804 class Attribute<VR::PN, TVM> : public StringAttribute<TVM> 00805 { 00806 }; 00807 #endif 00808 00809 #if 0 00810 00811 // Implementation for the undefined length (dynamically allocated array) 00812 template<int TVR> 00813 class Attribute<TVR, VM::VM1_n> 00814 { 00815 public: 00816 // This the way to prevent default initialization 00817 explicit Attribute() { Internal=0; Length=0; } 00818 ~Attribute() { 00819 delete[] Internal; 00820 Internal = 0; 00821 } 00822 00823 // Length manipulation 00824 // SetLength should really be protected anyway...all operation 00825 // should go through SetArray 00826 unsigned long GetLength() const { return Length; } 00827 typedef typename VRToType<TVR>::Type ArrayType; 00828 void SetLength(unsigned long len) { 00829 const unsigned int size = sizeof(ArrayType); 00830 if( len ) { 00831 if( len > Length ) { 00832 // perform realloc 00833 assert( (len / size) * size == len ); 00834 ArrayType *internal = new ArrayType[len / size]; 00835 memcpy(internal, Internal, Length * size); 00836 delete[] Internal; 00837 Internal = internal; 00838 } 00839 } 00840 Length = len / size; 00841 } 00842 00843 // If save is set to zero user should not delete the pointer 00844 //void SetArray(const typename VRToType<TVR>::Type *array, int len, bool save = false) 00845 void SetArray(const ArrayType *array, unsigned long len, 00846 bool save = false) { 00847 if( save ) { 00848 SetLength(len); // realloc 00849 memcpy(Internal, array, len/*/sizeof(ArrayType)*/); 00850 } 00851 else { 00852 // TODO rewrite this stupid code: 00853 Length = len; 00854 //Internal = array; 00855 assert(0); 00856 } 00857 } 00858 // Implementation of Print is common to all Mode (ASCII/Binary) 00859 void Print(std::ostream &_os) const { 00860 assert( Length ); 00861 assert( Internal ); 00862 _os << Internal[0]; // VM is at least garantee to be one 00863 const unsigned long length = GetLength() < 25 ? GetLength() : 25; 00864 for(unsigned long i=1; i<length; ++i) 00865 _os << "," << Internal[i]; 00866 } 00867 void Read(std::istream &_is) { 00868 EncodingImplementation<VRToEncoding<TVR>::Mode>::Read(Internal, 00869 GetLength(),_is); 00870 } 00871 void Write(std::ostream &_os) const { 00872 EncodingImplementation<VRToEncoding<TVR>::Mode>::Write(Internal, 00873 GetLength(),_os); 00874 } 00875 00876 Attribute(const Attribute&_val) { 00877 if( this != &_val) { 00878 *this = _val; 00879 } 00880 } 00881 00882 Attribute &operator=(const Attribute &_val) { 00883 Length = 0; // SYITF 00884 Internal = 0; 00885 SetArray(_val.Internal, _val.Length, true); 00886 return *this; 00887 } 00888 00889 private: 00890 typename VRToType<TVR>::Type *Internal; 00891 unsigned long Length; // unsigned int ?? 00892 }; 00893 00894 //template <int TVM = VM::VM1_n> 00895 //class Attribute<VR::OB, TVM > : public Attribute<VR::OB, VM::VM1_n> {}; 00896 00897 // Partial specialization for derivatives of 1-n : 2-n, 3-n ... 00898 template<int TVR> 00899 class Attribute<TVR, VM::VM2_n> : public Attribute<TVR, VM::VM1_n> 00900 { 00901 public: 00902 typedef Attribute<TVR, VM::VM1_n> Parent; 00903 void SetLength(int len) { 00904 if( len <= 1 ) return; 00905 Parent::SetLength(len); 00906 } 00907 }; 00908 template<int TVR> 00909 class Attribute<TVR, VM::VM2_2n> : public Attribute<TVR, VM::VM2_n> 00910 { 00911 public: 00912 typedef Attribute<TVR, VM::VM2_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_n> : public Attribute<TVR, VM::VM1_n> 00920 { 00921 public: 00922 typedef Attribute<TVR, VM::VM1_n> Parent; 00923 void SetLength(int len) { 00924 if( len <= 2 ) return; 00925 Parent::SetLength(len); 00926 } 00927 }; 00928 template<int TVR> 00929 class Attribute<TVR, VM::VM3_3n> : public Attribute<TVR, VM::VM3_n> 00930 { 00931 public: 00932 typedef Attribute<TVR, VM::VM3_n> Parent; 00933 void SetLength(int len) { 00934 if( len % 3 ) return; 00935 Parent::SetLength(len); 00936 } 00937 }; 00938 00939 00940 //template<int T> struct VRToLength; 00941 //template <> struct VRToLength<VR::AS> 00942 //{ enum { Length = VM::VM1 }; } 00943 //template<> 00944 //class Attribute<VR::AS> : public Attribute<VR::AS, VRToLength<VR::AS>::Length > 00945 00946 // only 0010 1010 AS 1 Patient’s Age 00947 template<> 00948 class Attribute<VR::AS, VM::VM5> 00949 { 00950 public: 00951 char Internal[VMToLength<VM::VM5>::Length]; 00952 void Print(std::ostream &_os) const { 00953 _os << Internal; 00954 } 00955 }; 00956 00957 template <> 00958 class Attribute<VR::OB, VM::VM1> : public Attribute<VR::OB, VM::VM1_n> {}; 00959 // Make it impossible to compile any other cases: 00960 template <int TVM> class Attribute<VR::OB, TVM>; 00961 00962 // Same for OW: 00963 template <> 00964 class Attribute<VR::OW, VM::VM1> : public Attribute<VR::OW, VM::VM1_n> {}; 00965 // Make it impossible to compile any other cases: 00966 template <int TVM> class Attribute<VR::OW, TVM>; 00967 #endif 00968 00969 #if 0 00970 template<> 00971 class Attribute<0x7fe0,0x0010, VR::OW, VM::VM1> 00972 { 00973 public: 00974 char *Internal; 00975 unsigned long Length; // unsigned int ?? 00976 00977 void Print(std::ostream &_os) const { 00978 _os << Internal[0]; 00979 } 00980 void SetBytes(char *bytes, unsigned long length) { 00981 Internal = bytes; 00982 Length = length; 00983 } 00984 void Read(std::istream &_is) { 00985 uint16_t c[2]; 00986 _is.read((char*)&c, 4); 00987 uint32_t l; 00988 _is.read((char*)&l, 4); 00989 Length = l; 00990 _is.read( Internal, Length ); 00991 } 00992 void Write(std::ostream &_os) const { 00993 uint16_t c[] = {0x7fe0, 0x0010}; 00994 _os.write((char*)&c, 4); 00995 _os.write((char*)&Length, 4); 00996 _os.write( Internal, Length ); 00997 } 00998 }; 00999 #endif 01000 01001 /* 01002 // Removing Attribute for SQ for now... 01003 template<uint16_t Group, uint16_t Element, typename SQA> 01004 class Attribute<Group,Element, VR::SQ, VM::VM1, SQA> 01005 { 01006 public: 01007 SQA sqa; 01008 void Print(std::ostream &_os) const { 01009 _os << Tag(Group,Element); 01010 sqa.Print(_os << std::endl << '\t'); 01011 } 01012 void Write(std::ostream &_os) const { 01013 uint16_t c[] = {Group, Element}; 01014 _os.write((char*)&c, 4); 01015 uint32_t undef = 0xffffffff; 01016 _os.write((char*)&undef, 4); 01017 uint16_t item_beg[] = {0xfffe,0xe000}; 01018 _os.write((char*)&item_beg, 4); 01019 _os.write((char*)&undef, 4); 01020 sqa.Write(_os); 01021 uint16_t item_end[] = {0xfffe,0xe00d}; 01022 _os.write((char*)&item_end, 4); 01023 uint32_t zero = 0x0; 01024 _os.write((char*)&zero, 4); 01025 uint16_t seq_end[] = {0xfffe, 0xe0dd}; 01026 _os.write((char*)&seq_end, 4); 01027 _os.write((char*)&zero, 4); 01028 } 01029 }; 01030 */ 01031 01037 } // namespace gdcm 01038 01039 #endif //GDCMATTRIBUTE_H