00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "gdcmDataEntry.h"
00020 #include "gdcmVR.h"
00021 #include "gdcmTS.h"
00022 #include "gdcmGlobal.h"
00023 #include "gdcmUtil.h"
00024 #include "gdcmDebug.h"
00025
00026 #include <fstream>
00027
00028 #if defined(__BORLANDC__)
00029 #include <mem.h>
00030 #include <stdlib.h>
00031 #include <ctype.h>
00032 #endif
00033
00034 namespace GDCM_NAME_SPACE
00035 {
00036
00037 #define MAX_SIZE_PRINT_ELEMENT_VALUE 0x7fffffff
00038 uint32_t DataEntry::MaxSizePrintEntry = MAX_SIZE_PRINT_ELEMENT_VALUE;
00039
00040
00041
00048 DataEntry::DataEntry(uint16_t group,uint16_t elem,
00049 VRKey const &vr)
00050 : DocEntry(group,elem,vr)
00051 {
00052 State = STATE_LOADED;
00053 Flag = FLAG_NONE;
00054
00055 StrArea = 0;
00056 BinArea = 0;
00057 SelfArea = true;
00058 }
00059
00064 DataEntry::DataEntry(DocEntry *e)
00065
00066 : DocEntry(e->GetGroup(),e->GetElement(), e->GetVR() )
00067 {
00068 Flag = FLAG_NONE;
00069 BinArea = 0;
00070
00071 SelfArea = true;
00072
00073 Copy(e);
00074 }
00075
00079 DataEntry::~DataEntry ()
00080 {
00081 DeleteBinArea();
00082
00083 }
00084
00085
00086
00087
00088
00089
00095 void DataEntry::SetBinArea( uint8_t *area, bool self )
00096 {
00097 DeleteBinArea();
00098
00099 BinArea = area;
00100 SelfArea = self;
00101
00102 State = STATE_LOADED;
00103 }
00109 void DataEntry::CopyBinArea( uint8_t *area, uint32_t length )
00110 {
00111 DeleteBinArea();
00112
00113 uint32_t lgh = length + length%2;
00114 SetLength(lgh);
00115
00116 if( area && length > 0 )
00117 {
00118 NewBinArea();
00119 memcpy(BinArea,area,length);
00120 if( length!=lgh )
00121 BinArea[length]=0;
00122
00123 State = STATE_LOADED;
00124 }
00125 }
00126
00132 void DataEntry::SetValue(const uint32_t &id, const double &val)
00133 {
00134 if( !BinArea )
00135 NewBinArea();
00136 State = STATE_LOADED;
00137
00138 if( id > GetValueCount() )
00139 {
00140 gdcmErrorMacro("Index (" << id << ") is greater than the data size");
00141 return;
00142 }
00143
00144 const VRKey &vr = GetVR();
00145 if( vr == "US" || vr == "SS" )
00146 {
00147 uint16_t *data = (uint16_t *)BinArea;
00148 data[id] = (uint16_t)val;
00149 }
00150 else if( vr == "UL" || vr == "SL" )
00151 {
00152 uint32_t *data = (uint32_t *)BinArea;
00153 data[id] = (uint32_t)val;
00154 }
00155 else if( vr == "FL" )
00156 {
00157 float *data = (float *)BinArea;
00158 data[id] = (float)val;
00159 }
00160 else if( vr == "FD" )
00161 {
00162 double *data = (double *)BinArea;
00163 data[id] = (double)val;
00164 }
00165 else if( Global::GetVR()->IsVROfStringRepresentable(vr) )
00166 {
00167 gdcmErrorMacro("SetValue on String representable not implemented yet");
00168 }
00169 else
00170 {
00171 BinArea[id] = (uint8_t)val;
00172 }
00173 }
00180 double DataEntry::GetValue(const uint32_t &id) const
00181 {
00182 if( !BinArea )
00183 {
00184 if (GetLength() != 0)
00186 gdcmErrorMacro("BinArea not set " << std::hex
00187 << GetGroup() << " " << GetElement()
00188 << " Can't get the value");
00189 return 0.0;
00190 }
00191
00192 uint32_t count = GetValueCount();
00193 if( id > count )
00194 {
00195 gdcmErrorMacro("Index (" << id << ") is greater than the data size");
00196 return 0.0;
00197 }
00198
00199
00200
00201
00202 const VRKey &vr = GetVR();
00203
00204 if( vr == "US" || vr == "SS" )
00205 return ((uint16_t *)BinArea)[id];
00206 else if( vr == "UL" || vr == "SL" )
00207 return ((uint32_t *)BinArea)[id];
00208 else if( vr == "FL" )
00209 return ((float *)BinArea)[id];
00210 else if( vr == "FD" )
00211 return ((double *)BinArea)[id];
00212 else if( Global::GetVR()->IsVROfStringRepresentable(vr) )
00213 {
00214
00215 if( GetLength() )
00216 {
00217
00218 double val;
00219 char *tmp = new char[GetLength()+1];
00220 memcpy(tmp,BinArea,GetLength());
00221 tmp[GetLength()]=0;
00222
00223 if( count == 0 )
00224 {
00225 val = atof(tmp);
00226 }
00227 else
00228 {
00229 count = id;
00230 char *beg = tmp;
00231 for(uint32_t i=0;i<GetLength();i++)
00232 {
00233 if( tmp[i] == '\\' )
00234 {
00235 if( count == 0 )
00236 {
00237 tmp[i] = 0;
00238 break;
00239 }
00240 else
00241 {
00242 count--;
00243 beg = &(tmp[i+1]);
00244 }
00245 }
00246 }
00247 val = atof(beg);
00248 }
00249
00250 delete[] tmp;
00251 return val;
00252 }
00253 else
00254 return 0.0;
00255 }
00256 else
00257 return BinArea[id];
00258 }
00259
00263 bool DataEntry::IsValueCountValid()
00264 {
00265 uint32_t vm;
00266 const std::string &strVM = GetVM();
00267 uint32_t vc = GetValueCount();
00268 bool valid = vc == 0;
00269 if( valid )
00270 return true;
00271
00272
00273
00274 if( strVM == "1-n" )
00275 {
00276
00277 valid = vc >= 1;
00278 }
00279 else
00280 {
00281 std::istringstream os;
00282 os.str( strVM );
00283 os >> vm;
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302 valid = vc == vm;
00303 }
00304 return valid;
00305 }
00306
00310 uint32_t DataEntry::GetValueCount( ) const
00311 {
00312 const VRKey &vr = GetVR();
00313 if( vr == "US" || vr == "SS" )
00314 return GetLength()/sizeof(uint16_t);
00315 else if( vr == "UL" || vr == "SL" )
00316 return GetLength()/sizeof(uint32_t);
00317 else if( vr == "FL" || vr == "OF" )
00318 return GetLength()/4 ;
00319 else if( vr == "FD" )
00320 return GetLength()/8;
00321 else if( Global::GetVR()->IsVROfStringRepresentable(vr) )
00322 {
00323
00324 if( !GetLength() )
00325 return 0;
00326
00327 uint32_t count = 1;
00328 for(uint32_t i=0;i<GetLength();i++)
00329 {
00330 if( BinArea[i] == '\\')
00331 count++;
00332 }
00333 return count;
00334 }
00335 return GetLength();
00336 }
00337
00343 bool DataEntry::GetDSValue(std::vector <double> &valueVector)
00344 {
00346 std::vector<std::string> tokens;
00347
00348 if (GetVR() != "DS")
00349 return false;
00350
00351 Util::Tokenize ( GetString().c_str(), tokens, "\\" );
00352
00353 int nbValues= tokens.size();
00354 if (nbValues == 0)
00355 return false;
00356
00357 for (int loop=0; loop<nbValues; loop++)
00358 valueVector.push_back(atof(tokens[loop].c_str()));
00359
00360 return true;
00361 }
00362
00367 void DataEntry::SetString(std::string const &value)
00368 {
00369 DeleteBinArea();
00370 const VRKey &vr = GetVR();
00371 if ( vr == "US" || vr == "SS" )
00372 {
00373 std::vector<std::string> tokens;
00374 Util::Tokenize (value, tokens, "\\");
00375 SetLength(tokens.size()*sizeof(uint16_t));
00376 NewBinArea();
00377
00378 uint16_t *data = (uint16_t *)BinArea;
00379 for (unsigned int i=0; i<tokens.size();i++)
00380 data[i] = atoi(tokens[i].c_str());
00381 tokens.clear();
00382 }
00383 else if ( vr == "UL" || vr == "SL" )
00384 {
00385 std::vector<std::string> tokens;
00386 Util::Tokenize (value, tokens, "\\");
00387 SetLength(tokens.size()*sizeof(uint32_t));
00388 NewBinArea();
00389
00390 uint32_t *data = (uint32_t *)BinArea;
00391 for (unsigned int i=0; i<tokens.size();i++)
00392 data[i] = atoi(tokens[i].c_str());
00393 tokens.clear();
00394 }
00395 else if ( vr == "FL" )
00396 {
00397 std::vector<std::string> tokens;
00398 Util::Tokenize (value, tokens, "\\");
00399 SetLength(tokens.size()*sizeof(float));
00400 NewBinArea();
00401
00402 float *data = (float *)BinArea;
00403 for (unsigned int i=0; i<tokens.size();i++)
00404 data[i] = (float)atof(tokens[i].c_str());
00405 tokens.clear();
00406 }
00407 else if ( vr == "FD" )
00408 {
00409 std::vector<std::string> tokens;
00410 Util::Tokenize (value, tokens, "\\");
00411 SetLength(tokens.size()*sizeof(double));
00412 NewBinArea();
00413
00414 double *data = (double *)BinArea;
00415 for (unsigned int i=0; i<tokens.size();i++)
00416 data[i] = atof(tokens[i].c_str());
00417 tokens.clear();
00418 }
00419 else
00420 {
00421 size_t l = value.size();
00422 SetLength(l + l%2);
00423 NewBinArea();
00424 memcpy(BinArea, value.c_str(), l);
00425 if (l%2)
00426 if ( vr == "UI" )
00427 BinArea[l] = '\0';
00428 else
00429 BinArea[l] = ' ';
00430 }
00431 State = STATE_LOADED;
00432 }
00436 std::string const &DataEntry::GetString() const
00437 {
00438 static std::ostringstream s;
00439 const VRKey &vr = GetVR();
00440 s.str("");
00441
00442 if (!StrArea)
00443 StrArea = new std::string();
00444 else
00445 *StrArea="";
00446
00447 if( !BinArea )
00448 return *StrArea;
00449
00450
00451 if( vr == "US" )
00452 {
00453 uint16_t *data=(uint16_t *)BinArea;
00454 for (unsigned int i=0; i < GetValueCount(); i++)
00455 {
00456 if( i!=0 )
00457 s << '\\';
00458 s << data[i];
00459 }
00460 *StrArea=s.str();
00461 }
00462 else if (vr == "SS" )
00463 {
00464 int16_t *data=(int16_t *)BinArea;
00465 for (unsigned int i=0; i < GetValueCount(); i++)
00466 {
00467 if( i!=0 )
00468 s << '\\';
00469 s << data[i];
00470 }
00471 *StrArea=s.str();
00472 }
00473 else if( vr == "UL" )
00474 {
00475 uint32_t *data=(uint32_t *)BinArea;
00476 for (unsigned int i=0; i < GetValueCount(); i++)
00477 {
00478 if( i!=0 )
00479 s << '\\';
00480 s << data[i];
00481 }
00482 *StrArea=s.str();
00483 }
00484 else if( vr == "SL" )
00485 {
00486 int32_t *data=(int32_t *)BinArea;
00487 for (unsigned int i=0; i < GetValueCount(); i++)
00488 {
00489 if( i!=0 )
00490 s << '\\';
00491 s << data[i];
00492 }
00493 *StrArea=s.str();
00494 } else if( vr == "FL" )
00495 {
00496 float *data=(float *)BinArea;
00497 for (unsigned int i=0; i < GetValueCount(); i++)
00498 {
00499 if( i!=0 )
00500 s << '\\';
00501 s << data[i];
00502 }
00503 *StrArea=s.str();
00504 }
00505 else if( vr == "FD" )
00506 {
00507 double *data=(double *)BinArea;
00508 for (unsigned int i=0; i < GetValueCount(); i++)
00509 {
00510 if( i!=0 )
00511 s << '\\';
00512 s << data[i];
00513 }
00514 *StrArea=s.str();
00515 }
00516 else
00517 {
00518 StrArea->append((const char *)BinArea,GetLength());
00519
00520 if ( GetLength()%2)
00521 StrArea->append(" ",1); }
00522 return *StrArea;
00523 }
00524
00525
00531 void DataEntry::Copy(DocEntry *doc)
00532 {
00533 DocEntry::Copy(doc);
00534
00535 DataEntry *entry = dynamic_cast<DataEntry *>(doc);
00536 if ( entry )
00537 {
00538 State = entry->State;
00539 Flag = entry->Flag;
00540 CopyBinArea(entry->BinArea,entry->GetLength());
00541 }
00542 }
00543
00549 void DataEntry::WriteContent(std::ofstream *fp, FileType filetype,
00550 bool insideMetaElements)
00551 {
00552
00553 DocEntry::WriteContent(fp, filetype, insideMetaElements);
00554
00555 if ( GetGroup() == 0xfffe )
00556 {
00557 return;
00558 }
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579 uint8_t *data = BinArea;
00580 size_t l = GetLength();
00581
00582
00583
00584 if (BinArea)
00585 {
00586 #if defined(GDCM_WORDS_BIGENDIAN) || defined(GDCM_FORCE_BIGENDIAN_EMULATION)
00587 unsigned short vrLgth =
00588 Global::GetVR()->GetAtomicElementLength(this->GetVR());
00589 unsigned int i;
00590 switch(vrLgth)
00591 {
00592 case 1:
00593 {
00594 binary_write (*fp, data, l );
00595 break;
00596 }
00597 case 2:
00598 {
00599 uint16_t *data16 = (uint16_t *)data;
00600 for(i=0;i<l/vrLgth;i++)
00601 binary_write( *fp, data16[i]);
00602 break;
00603 }
00604 case 4:
00605 {
00606 uint32_t *data32 = (uint32_t *)data;
00607 for(i=0;i<l/vrLgth;i++)
00608 binary_write( *fp, data32[i]);
00609 break;
00610 }
00611 case 8:
00612 {
00613 double *data64 = (double *)data;
00614 for(i=0;i<l/vrLgth;i++)
00615 binary_write( *fp, data64[i]);
00616 break;
00617 }
00618 }
00619 #else
00620 binary_write (*fp, data, l );
00621 #endif //GDCM_WORDS_BIGENDIAN
00622
00623 }
00624 else
00625 {
00626
00627 if (l != 0)
00628 {
00629
00630
00631
00632 gdcmDebugMacro ("Nothing was loaded, but we need to skip space on disc. "
00633 << "Length =" << l << " for " << GetKey() );
00634 fp->seekp(l, std::ios::cur);
00635 }
00636 }
00637
00638
00639 if (l%2)
00640 fp->seekp(1, std::ios::cur);
00641 }
00642
00647 uint32_t DataEntry::ComputeFullLength()
00648 {
00649 return GetFullLength();
00650 }
00651
00652
00653
00656 void DataEntry::NewBinArea( )
00657 {
00658 DeleteBinArea();
00659 if( GetLength() > 0 )
00660 BinArea = new uint8_t[GetLength()];
00661 SelfArea = true;
00662 }
00665 void DataEntry::DeleteBinArea(void)
00666 {
00667 if (BinArea && SelfArea)
00668 {
00669 delete[] BinArea;
00670 BinArea = NULL;
00671 }
00672 if (StrArea)
00673 {
00674 delete StrArea;
00675 StrArea = 0;
00676 }
00677 }
00678
00679
00680
00681
00682
00683
00689 void DataEntry::Print(std::ostream &os, std::string const & )
00690 {
00691 os << "D ";
00692 DocEntry::Print(os);
00693
00694 uint16_t g = GetGroup();
00695 if (g == 0xfffe)
00696 {
00697 return;
00698 }
00699
00700 std::ostringstream s;
00701 TSAtr v;
00702
00703 if( BinArea )
00704 {
00705 v = GetString();
00706 const VRKey &vr = GetVR();
00707
00708 if( vr == "US" || vr == "SS" || vr == "UL" || vr == "SL"
00709 || vr == "FL" || vr == "FD")
00710 s << " [" << GetString() << "]";
00711 else
00712 {
00713 if(Global::GetVR()->IsVROfStringRepresentable(vr))
00714 {
00715
00716 std::string cleanString = Util::CreateCleanString(v);
00717 if ( cleanString.length() <= GetMaxSizePrintEntry()
00718 || PrintLevel >= 3
00719 || IsNotLoaded() )
00720
00721
00722
00723
00724 {
00725 s << " [" << cleanString << "]";
00726 }
00727 else
00728 {
00729 s << " [GDCM_NAME_SPACE::too long for print (" << cleanString.length() << ") ]";
00730 }
00731 }
00732 else
00733 {
00734
00735
00736
00737
00738 if ( Util::IsCleanArea( GetBinArea(), GetLength() ) )
00739 {
00740
00741
00742 std::string cleanString =
00743 Util::CreateCleanString( BinArea,GetLength() );
00744 s << " [" << cleanString << "]";
00745 }
00746 else
00747 {
00748 s << " [" << GDCM_BINLOADED << ";"
00749 << "length = " << GetLength() << "]";
00750 }
00751 }
00752 }
00753 }
00754 else
00755 {
00756 if( IsNotLoaded() )
00757 s << " [" << GDCM_NOTLOADED << "]";
00758 else if( IsUnfound() )
00759 s << " [" << GDCM_UNFOUND << "]";
00760 else if( IsUnread() )
00761 s << " [" << GDCM_UNREAD << "]";
00762 else if ( GetLength() == 0 )
00763 s << " []";
00764 }
00765
00766 if( IsPixelData() )
00767 s << " (" << GDCM_PIXELDATA << ")";
00768
00769
00770
00771 if(BinArea)
00772 {
00773 const uint16_t &gr = GetGroup();
00774 const uint16_t &elt = GetElement();
00775 TS *ts = Global::GetTS();
00776
00777 if (gr == 0x0002)
00778 {
00779
00780 if ( elt == 0x0010 || elt == 0x0002 )
00781 {
00782 if ( v.length() != 0 )
00783 {
00784 if ( ! isdigit((unsigned char)v[v.length()-1]) )
00785 {
00786 v.erase(v.length()-1, 1);
00787 }
00788 }
00789 s << " ==>\t[" << ts->GetValue(v) << "]";
00790 }
00791 }
00792 else if (gr == 0x0008)
00793 {
00794 if ( elt == 0x0016 || elt == 0x1150 )
00795 {
00796 if ( v.length() != 0 )
00797 {
00798 if ( ! isdigit((unsigned char)v[v.length()-1]) )
00799 {
00800 v.erase(v.length()-1, 1);
00801 }
00802 }
00803 s << " ==>\t[" << ts->GetValue(v) << "]";
00804 }
00805 }
00806 else if (gr == 0x0004)
00807 {
00808 if ( elt == 0x1510 || elt == 0x1512 )
00809 {
00810 if ( v.length() != 0 )
00811 {
00812 if ( ! isdigit((unsigned char)v[v.length()-1]) )
00813 {
00814 v.erase(v.length()-1, 1);
00815 }
00816 }
00817 s << " ==>\t[" << ts->GetValue(v) << "]";
00818 }
00819 }
00820 }
00821
00822 os << s.str();
00823 }
00824
00825
00826 }
00827