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 namespace gdcm
00029 {
00030
00031 #define MAX_SIZE_PRINT_ELEMENT_VALUE 0x7fffffff
00032 uint32_t DataEntry::MaxSizePrintEntry = MAX_SIZE_PRINT_ELEMENT_VALUE;
00033
00034
00035
00040 DataEntry::DataEntry(DictEntry *e)
00041 : DocEntry(e)
00042 {
00043 State = STATE_LOADED;
00044 Flag = FLAG_NONE;
00045
00046 BinArea = 0;
00047 SelfArea = true;
00048 }
00049
00054 DataEntry::DataEntry(DocEntry *e)
00055 : DocEntry(e->GetDictEntry())
00056 {
00057 Flag = FLAG_NONE;
00058 BinArea = 0;
00059 SelfArea = true;
00060
00061 Copy(e);
00062 }
00063
00067 DataEntry::~DataEntry ()
00068 {
00069 DeleteBinArea();
00070 }
00071
00072
00073
00074
00075
00076
00082 void DataEntry::SetBinArea( uint8_t *area, bool self )
00083 {
00084 DeleteBinArea();
00085
00086 BinArea = area;
00087 SelfArea = self;
00088
00089 State = STATE_LOADED;
00090 }
00096 void DataEntry::CopyBinArea( uint8_t *area, uint32_t length )
00097 {
00098 DeleteBinArea();
00099
00100 uint32_t lgh = length + length%2;
00101 SetLength(lgh);
00102
00103 if( area && length > 0 )
00104 {
00105 NewBinArea();
00106 memcpy(BinArea,area,length);
00107 if( length!=lgh )
00108 BinArea[length]=0;
00109
00110 State = STATE_LOADED;
00111 }
00112 }
00113
00119 void DataEntry::SetValue(const uint32_t &id, const double &val)
00120 {
00121 if( !BinArea )
00122 NewBinArea();
00123 State = STATE_LOADED;
00124
00125 if( id > GetValueCount() )
00126 {
00127 gdcmErrorMacro("Index (" << id << ")is greater than the data size");
00128 return;
00129 }
00130
00131 const VRKey &vr = GetVR();
00132 if( vr == "US" || vr == "SS" )
00133 {
00134 uint16_t *data = (uint16_t *)BinArea;
00135 data[id] = (uint16_t)val;
00136 }
00137 else if( vr == "UL" || vr == "SL" )
00138 {
00139 uint32_t *data = (uint32_t *)BinArea;
00140 data[id] = (uint32_t)val;
00141 }
00142 else if( vr == "FL" )
00143 {
00144 float *data = (float *)BinArea;
00145 data[id] = (float)val;
00146 }
00147 else if( vr == "FD" )
00148 {
00149 double *data = (double *)BinArea;
00150 data[id] = (double)val;
00151 }
00152 else if( Global::GetVR()->IsVROfStringRepresentable(vr) )
00153 {
00154 gdcmErrorMacro("SetValue on String representable not implemented yet");
00155 }
00156 else
00157 {
00158 BinArea[id] = (uint8_t)val;
00159 }
00160 }
00168 double DataEntry::GetValue(const uint32_t &id) const
00169 {
00170 if( !BinArea )
00171 {
00172 gdcmErrorMacro("BinArea not set. Can't get the value");
00173 return 0.0;
00174 }
00175
00176 uint32_t count = GetValueCount();
00177 if( id > count )
00178 {
00179 gdcmErrorMacro("Index (" << id << ")is greater than the data size");
00180 return 0.0;
00181 }
00182
00183
00184
00185
00186 const VRKey &vr = GetVR();
00187 if( vr == "US" || vr == "SS" )
00188 return ((uint16_t *)BinArea)[id];
00189 else if( vr == "UL" || vr == "SL" )
00190 return ((uint32_t *)BinArea)[id];
00191 else if( vr == "FL" )
00192 return ((float *)BinArea)[id];
00193 else if( vr == "FD" )
00194 return ((double *)BinArea)[id];
00195 else if( Global::GetVR()->IsVROfStringRepresentable(vr) )
00196 {
00197 if( GetLength() )
00198 {
00199
00200 double val;
00201 char *tmp = new char[GetLength()+1];
00202 memcpy(tmp,BinArea,GetLength());
00203 tmp[GetLength()]=0;
00204
00205 if( count == 0 )
00206 {
00207 val = atof(tmp);
00208 }
00209 else
00210 {
00211 count = id;
00212 char *beg = tmp;
00213 for(uint32_t i=0;i<GetLength();i++)
00214 {
00215 if( tmp[i] == '\\' )
00216 {
00217 if( count == 0 )
00218 {
00219 tmp[i] = 0;
00220 break;
00221 }
00222 else
00223 {
00224 count--;
00225 beg = &(tmp[i+1]);
00226 }
00227 }
00228 }
00229 val = atof(beg);
00230 }
00231
00232 delete[] tmp;
00233 return val;
00234 }
00235 else
00236 return 0.0;
00237 }
00238 else
00239 return BinArea[id];
00240 }
00241
00245 bool DataEntry::IsValueCountValid() const
00246 {
00247 uint32_t vm;
00248 const std::string &strVM = GetVM();
00249 uint32_t vc = GetValueCount();
00250 bool valid = vc == 0;
00251 if( valid )
00252 return true;
00253
00254
00255
00256 if( strVM == "1-n" )
00257 {
00258
00259 valid = vc >= 1;
00260 }
00261 else
00262 {
00263 std::istringstream os;
00264 os.str( strVM );
00265 os >> vm;
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284 valid = vc == vm;
00285 }
00286 return valid;
00287 }
00288
00292 uint32_t DataEntry::GetValueCount( ) const
00293 {
00294 const VRKey &vr = GetVR();
00295 if( vr == "US" || vr == "SS" )
00296 return GetLength()/sizeof(uint16_t);
00297 else if( vr == "UL" || vr == "SL" )
00298 return GetLength()/sizeof(uint32_t);
00299 else if( vr == "FL" || vr == "OF" )
00300 return GetLength()/4 ;
00301 else if( vr == "FD" )
00302 return GetLength()/8;
00303 else if( Global::GetVR()->IsVROfStringRepresentable(vr) )
00304 {
00305
00306 if( !GetLength() )
00307 return 0;
00308
00309 uint32_t count = 1;
00310 for(uint32_t i=0;i<GetLength();i++)
00311 {
00312 if( BinArea[i] == '\\')
00313 count++;
00314 }
00315 return count;
00316 }
00317 return GetLength();
00318 }
00323 void DataEntry::SetString(std::string const &value)
00324 {
00325 DeleteBinArea();
00326
00327 const VRKey &vr = GetVR();
00328 if ( vr == "US" || vr == "SS" )
00329 {
00330 std::vector<std::string> tokens;
00331 Util::Tokenize (value, tokens, "\\");
00332 SetLength(tokens.size()*sizeof(uint16_t));
00333 NewBinArea();
00334
00335 uint16_t *data = (uint16_t *)BinArea;
00336 for (unsigned int i=0; i<tokens.size();i++)
00337 data[i] = atoi(tokens[i].c_str());
00338 tokens.clear();
00339 }
00340 else if ( vr == "UL" || vr == "SL" )
00341 {
00342 std::vector<std::string> tokens;
00343 Util::Tokenize (value, tokens, "\\");
00344 SetLength(tokens.size()*sizeof(uint32_t));
00345 NewBinArea();
00346
00347 uint32_t *data = (uint32_t *)BinArea;
00348 for (unsigned int i=0; i<tokens.size();i++)
00349 data[i] = atoi(tokens[i].c_str());
00350 tokens.clear();
00351 }
00352 else if ( vr == "FL" )
00353 {
00354 std::vector<std::string> tokens;
00355 Util::Tokenize (value, tokens, "\\");
00356 SetLength(tokens.size()*sizeof(float));
00357 NewBinArea();
00358
00359 float *data = (float *)BinArea;
00360 for (unsigned int i=0; i<tokens.size();i++)
00361 data[i] = (float)atof(tokens[i].c_str());
00362 tokens.clear();
00363 }
00364 else if ( vr == "FD" )
00365 {
00366 std::vector<std::string> tokens;
00367 Util::Tokenize (value, tokens, "\\");
00368 SetLength(tokens.size()*sizeof(double));
00369 NewBinArea();
00370
00371 double *data = (double *)BinArea;
00372 for (unsigned int i=0; i<tokens.size();i++)
00373 data[i] = atof(tokens[i].c_str());
00374 tokens.clear();
00375 }
00376 else
00377 {
00378 if( value.size() > 0 )
00379 {
00380 size_t l = value.size();
00381 SetLength(l + l%2);
00382 NewBinArea();
00383 memcpy(BinArea, value.c_str(), l);
00384 if (l%2)
00385 BinArea[l] = '\0';
00386 }
00387 }
00388 State = STATE_LOADED;
00389 }
00393 std::string const &DataEntry::GetString() const
00394 {
00395 static std::ostringstream s;
00396 const VRKey &vr = GetVR();
00397
00398 s.str("");
00399 StrArea="";
00400
00401 if( !BinArea )
00402 return StrArea;
00403
00404
00405
00406
00407 if( vr == "US" || vr == "SS" )
00408 {
00409 uint16_t *data=(uint16_t *)BinArea;
00410
00411 for (unsigned int i=0; i < GetValueCount(); i++)
00412 {
00413 if( i!=0 )
00414 s << '\\';
00415 s << data[i];
00416 }
00417 StrArea=s.str();
00418 }
00419
00420 else if( vr == "UL" || vr == "SL" )
00421 {
00422 uint32_t *data=(uint32_t *)BinArea;
00423
00424 for (unsigned int i=0; i < GetValueCount(); i++)
00425 {
00426 if( i!=0 )
00427 s << '\\';
00428 s << data[i];
00429 }
00430 StrArea=s.str();
00431 }
00432 else if( vr == "FL" )
00433 {
00434 float *data=(float *)BinArea;
00435
00436 for (unsigned int i=0; i < GetValueCount(); i++)
00437 {
00438 if( i!=0 )
00439 s << '\\';
00440 s << data[i];
00441 }
00442 StrArea=s.str();
00443 }
00444 else if( vr == "FD" )
00445 {
00446 double *data=(double *)BinArea;
00447
00448 for (unsigned int i=0; i < GetValueCount(); i++)
00449 {
00450 if( i!=0 )
00451 s << '\\';
00452 s << data[i];
00453 }
00454 StrArea=s.str();
00455 }
00456 else
00457 {
00458 StrArea.append((const char *)BinArea,GetLength());
00459
00460 if ( GetLength()%2)
00461 StrArea.append(" ",1);
00462 }
00463 return StrArea;
00464 }
00465
00471 void DataEntry::Copy(DocEntry *doc)
00472 {
00473 DocEntry::Copy(doc);
00474
00475 DataEntry *entry = dynamic_cast<DataEntry *>(doc);
00476 if ( entry )
00477 {
00478 State = entry->State;
00479 Flag = entry->Flag;
00480 CopyBinArea(entry->BinArea,entry->GetLength());
00481 }
00482 }
00483
00489 void DataEntry::WriteContent(std::ofstream *fp, FileType filetype)
00490 {
00491 DocEntry::WriteContent(fp, filetype);
00492
00493 if ( GetGroup() == 0xfffe )
00494 {
00495 return;
00496 }
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517 uint8_t *data = BinArea;
00518 size_t l = GetLength();
00519 gdcmDebugMacro("in DataEntry::WriteContent " << GetKey() << " AtomicLength: "
00520 << Global::GetVR()->GetAtomicElementLength(this->GetVR() )
00521 );
00522 if (BinArea)
00523 {
00524 #if defined(GDCM_WORDS_BIGENDIAN) || defined(GDCM_FORCE_BIGENDIAN_EMULATION)
00525 unsigned short vrLgth =
00526 Global::GetVR()->GetAtomicElementLength(this->GetVR());
00527 unsigned int i;
00528 switch(vrLgth)
00529 {
00530 case 1:
00531 {
00532 binary_write (*fp, data, l );
00533 break;
00534 }
00535 case 2:
00536 {
00537 uint16_t *data16 = (uint16_t *)data;
00538 for(i=0;i<l/vrLgth;i++)
00539 binary_write( *fp, data16[i]);
00540 break;
00541 }
00542 case 4:
00543 {
00544 uint32_t *data32 = (uint32_t *)data;
00545 for(i=0;i<l/vrLgth;i++)
00546 binary_write( *fp, data32[i]);
00547 break;
00548 }
00549 case 8:
00550 {
00551 double *data64 = (double *)data;
00552 for(i=0;i<l/vrLgth;i++)
00553 binary_write( *fp, data64[i]);
00554 break;
00555 }
00556 }
00557 #else
00558 binary_write (*fp, data, l );
00559 #endif //GDCM_WORDS_BIGENDIAN
00560
00561 }
00562 else
00563 {
00564
00565 if (l != 0)
00566 {
00567
00568
00569
00570 gdcmDebugMacro ("Nothing was loaded, but we need to skip space on disc. "
00571 << "Length =" << l << " for " << GetKey() );
00572 fp->seekp(l, std::ios::cur);
00573 }
00574 }
00575
00576
00577 if (l%2)
00578 fp->seekp(1, std::ios::cur);
00579 }
00580
00585 uint32_t DataEntry::ComputeFullLength()
00586 {
00587 return GetFullLength();
00588 }
00589
00590
00591
00593 void DataEntry::NewBinArea( )
00594 {
00595 DeleteBinArea();
00596 if( GetLength() > 0 )
00597 BinArea = new uint8_t[GetLength()];
00598 SelfArea = true;
00599 }
00601 void DataEntry::DeleteBinArea(void)
00602 {
00603 if (BinArea && SelfArea)
00604 {
00605 delete[] BinArea;
00606 BinArea = NULL;
00607 }
00608 }
00609
00610
00611
00612
00613
00614
00620 void DataEntry::Print(std::ostream &os, std::string const & )
00621 {
00622 os << "D ";
00623 DocEntry::Print(os);
00624
00625 uint16_t g = GetGroup();
00626 if (g == 0xfffe)
00627 {
00628 return;
00629 }
00630
00631 std::ostringstream s;
00632 TSAtr v;
00633
00634 if( BinArea )
00635 {
00636 v = GetString();
00637 const VRKey &vr = GetVR();
00638
00639 if( vr == "US" || vr == "SS" )
00640 s << " [" << GetString() << "]";
00641 else if( vr == "UL" || vr == "SL" )
00642 s << " [" << GetString() << "]";
00643 else if ( vr == "FL" )
00644 s << " [" << GetString() << "]";
00645 else if ( vr == "FD" )
00646 s << " [" << GetString() << "]";
00647 else
00648 {
00649 if(Global::GetVR()->IsVROfStringRepresentable(vr))
00650 {
00651
00652 std::string cleanString = Util::CreateCleanString(v);
00653 if ( cleanString.length() <= GetMaxSizePrintEntry()
00654 || PrintLevel >= 3
00655 || IsNotLoaded() )
00656
00657
00658
00659
00660 {
00661 s << " [" << cleanString << "]";
00662 }
00663 else
00664 {
00665 s << " [gdcm::too long for print (" << cleanString.length() << ") ]";
00666 }
00667 }
00668 else
00669 {
00670
00671
00672
00673
00674 if ( Util::IsCleanArea( GetBinArea(), GetLength() ) )
00675 {
00676
00677
00678 std::string cleanString =
00679 Util::CreateCleanString( BinArea,GetLength() );
00680 s << " [" << cleanString << "]";
00681 }
00682 else
00683 {
00684 s << " [" << GDCM_BINLOADED << ";"
00685 << "length = " << GetLength() << "]";
00686 }
00687 }
00688 }
00689 }
00690 else
00691 {
00692 if( IsNotLoaded() )
00693 s << " [" << GDCM_NOTLOADED << "]";
00694 else if( IsUnfound() )
00695 s << " [" << GDCM_UNFOUND << "]";
00696 else if( IsUnread() )
00697 s << " [" << GDCM_UNREAD << "]";
00698 else if ( GetLength() == 0 )
00699 s << " []";
00700 }
00701
00702 if( IsPixelData() )
00703 s << " (" << GDCM_PIXELDATA << ")";
00704
00705
00706
00707 if(BinArea)
00708 {
00709 const uint16_t &gr = GetGroup();
00710 const uint16_t &elt = GetElement();
00711 TS *ts = Global::GetTS();
00712
00713 if (gr == 0x0002)
00714 {
00715
00716 if ( elt == 0x0010 || elt == 0x0002 )
00717 {
00718 if ( v.length() != 0 )
00719 {
00720 if ( ! isdigit((unsigned char)v[v.length()-1]) )
00721 {
00722 v.erase(v.length()-1, 1);
00723 }
00724 }
00725 s << " ==>\t[" << ts->GetValue(v) << "]";
00726 }
00727 }
00728 else if (gr == 0x0008)
00729 {
00730 if ( elt == 0x0016 || elt == 0x1150 )
00731 {
00732 if ( v.length() != 0 )
00733 {
00734 if ( ! isdigit((unsigned char)v[v.length()-1]) )
00735 {
00736 v.erase(v.length()-1, 1);
00737 }
00738 }
00739 s << " ==>\t[" << ts->GetValue(v) << "]";
00740 }
00741 }
00742 else if (gr == 0x0004)
00743 {
00744 if ( elt == 0x1510 || elt == 0x1512 )
00745 {
00746 if ( v.length() != 0 )
00747 {
00748 if ( ! isdigit((unsigned char)v[v.length()-1]) )
00749 {
00750 v.erase(v.length()-1, 1);
00751 }
00752 }
00753 s << " ==>\t[" << ts->GetValue(v) << "]";
00754 }
00755 }
00756 }
00757
00758 os << s.str();
00759 }
00760
00761
00762 }
00763