00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "gdcmFile.h"
00032 #include "gdcmGlobal.h"
00033 #include "gdcmUtil.h"
00034 #include "gdcmDebug.h"
00035 #include "gdcmTS.h"
00036 #include "gdcmValEntry.h"
00037 #include "gdcmBinEntry.h"
00038 #include "gdcmSeqEntry.h"
00039 #include "gdcmRLEFramesInfo.h"
00040 #include "gdcmJPEGFragmentsInfo.h"
00041
00042 #include <stdio.h>
00043 #include <vector>
00044
00045 namespace gdcm
00046 {
00047
00048
00053 File::File( std::string const &filename )
00054 :Document( filename )
00055 {
00056 RLEInfo = new RLEFramesInfo;
00057 JPEGInfo = new JPEGFragmentsInfo;
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 const std::string &imgLocation = GetEntryValue(0x0028, 0x0200);
00071 if ( imgLocation == GDCM_UNFOUND )
00072 {
00073
00074 GrPixel = 0x7fe0;
00075 }
00076 else
00077 {
00078 GrPixel = (uint16_t) atoi( imgLocation.c_str() );
00079 }
00080
00081
00082
00083
00084 if ( GrPixel == 0xe07f )
00085 {
00086 GrPixel = 0x7fe0;
00087 }
00088
00089 if ( GrPixel != 0x7fe0 )
00090 {
00091
00092 NumPixel = 0x1010;
00093 }
00094 else
00095 {
00096 NumPixel = 0x0010;
00097 }
00098
00099
00100
00101
00102 DocEntry *entry = GetDocEntry(GrPixel, NumPixel);
00103 if ( entry != 0 )
00104 {
00105
00106 OpenFile();
00107 std::string ts = GetTransferSyntax();
00108 Fp->seekg( entry->GetOffset(), std::ios::beg );
00109 if ( Global::GetTS()->IsRLELossless(ts) )
00110 ComputeRLEInfo();
00111 else if ( Global::GetTS()->IsJPEG(ts) )
00112 ComputeJPEGFragmentInfo();
00113 CloseFile();
00114
00115
00116
00117
00118
00119
00120 BinEntry *oldEntry = dynamic_cast<BinEntry *>(entry);
00121 if(oldEntry)
00122 {
00123 std::string PixelVR;
00124
00125
00126 if ( GetBitsAllocated() == 8 || GetBitsAllocated() == 24 )
00127 PixelVR = "OB";
00128 else
00129 PixelVR = "OW";
00130
00131
00132 if( PixelVR != oldEntry->GetVR() )
00133 {
00134 DictEntry* newDict = NewVirtualDictEntry(GrPixel,NumPixel,
00135 PixelVR,"1","Pixel Data");
00136
00137 BinEntry *newEntry = new BinEntry(newDict);
00138 newEntry->Copy(entry);
00139 newEntry->SetBinArea(oldEntry->GetBinArea(),oldEntry->IsSelfArea());
00140 oldEntry->SetSelfArea(false);
00141
00142 RemoveEntry(oldEntry);
00143 AddEntry(newEntry);
00144 }
00145 }
00146 }
00147 }
00148
00152 File::File():
00153 Document()
00154 {
00155 RLEInfo = new RLEFramesInfo;
00156 JPEGInfo = new JPEGFragmentsInfo;
00157 InitializeDefaultFile();
00158 }
00159
00163 File::~File ()
00164 {
00165 if( RLEInfo )
00166 delete RLEInfo;
00167 if( JPEGInfo )
00168 delete JPEGInfo;
00169 }
00170
00171
00172
00181 bool File::IsReadable()
00182 {
00183 if( !Document::IsReadable() )
00184 {
00185 return false;
00186 }
00187
00188 const std::string &res = GetEntryValue(0x0028, 0x0005);
00189 if ( res != GDCM_UNFOUND && atoi(res.c_str()) > 4 )
00190 {
00191 return false;
00192 }
00193 if ( !GetDocEntry(0x0028, 0x0100) )
00194 {
00195 return false;
00196 }
00197 if ( !GetDocEntry(0x0028, 0x0101) )
00198 {
00199 return false;
00200 }
00201 if ( !GetDocEntry(0x0028, 0x0102) )
00202 {
00203 return false;
00204 }
00205 if ( !GetDocEntry(0x0028, 0x0103) )
00206 {
00207 return false;
00208 }
00209
00210 return true;
00211 }
00212
00217 int File::GetImageNumber()
00218 {
00219
00220
00221
00222
00223
00224
00225
00226 std::string strImNumber = GetEntryValue(0x0020,0x0013);
00227 if ( strImNumber != GDCM_UNFOUND )
00228 {
00229 return atoi( strImNumber.c_str() );
00230 }
00231 return 0;
00232 }
00233
00238 ModalityType File::GetModality()
00239 {
00240
00241 std::string strModality = GetEntryValue(0x0008,0x0060);
00242 if ( strModality != GDCM_UNFOUND )
00243 {
00244 if ( strModality.find("AU") < strModality.length()) return AU;
00245 else if ( strModality.find("AS") < strModality.length()) return AS;
00246 else if ( strModality.find("BI") < strModality.length()) return BI;
00247 else if ( strModality.find("CF") < strModality.length()) return CF;
00248 else if ( strModality.find("CP") < strModality.length()) return CP;
00249 else if ( strModality.find("CR") < strModality.length()) return CR;
00250 else if ( strModality.find("CT") < strModality.length()) return CT;
00251 else if ( strModality.find("CS") < strModality.length()) return CS;
00252 else if ( strModality.find("DD") < strModality.length()) return DD;
00253 else if ( strModality.find("DF") < strModality.length()) return DF;
00254 else if ( strModality.find("DG") < strModality.length()) return DG;
00255 else if ( strModality.find("DM") < strModality.length()) return DM;
00256 else if ( strModality.find("DS") < strModality.length()) return DS;
00257 else if ( strModality.find("DX") < strModality.length()) return DX;
00258 else if ( strModality.find("ECG") < strModality.length()) return ECG;
00259 else if ( strModality.find("EPS") < strModality.length()) return EPS;
00260 else if ( strModality.find("FA") < strModality.length()) return FA;
00261 else if ( strModality.find("FS") < strModality.length()) return FS;
00262 else if ( strModality.find("HC") < strModality.length()) return HC;
00263 else if ( strModality.find("HD") < strModality.length()) return HD;
00264 else if ( strModality.find("LP") < strModality.length()) return LP;
00265 else if ( strModality.find("LS") < strModality.length()) return LS;
00266 else if ( strModality.find("MA") < strModality.length()) return MA;
00267 else if ( strModality.find("MR") < strModality.length()) return MR;
00268 else if ( strModality.find("NM") < strModality.length()) return NM;
00269 else if ( strModality.find("OT") < strModality.length()) return OT;
00270 else if ( strModality.find("PT") < strModality.length()) return PT;
00271 else if ( strModality.find("RF") < strModality.length()) return RF;
00272 else if ( strModality.find("RG") < strModality.length()) return RG;
00273 else if ( strModality.find("RTDOSE") < strModality.length()) return RTDOSE;
00274 else if ( strModality.find("RTIMAGE") < strModality.length()) return RTIMAGE;
00275 else if ( strModality.find("RTPLAN") < strModality.length()) return RTPLAN;
00276 else if ( strModality.find("RTSTRUCT") < strModality.length()) return RTSTRUCT;
00277 else if ( strModality.find("SM") < strModality.length()) return SM;
00278 else if ( strModality.find("ST") < strModality.length()) return ST;
00279 else if ( strModality.find("TG") < strModality.length()) return TG;
00280 else if ( strModality.find("US") < strModality.length()) return US;
00281 else if ( strModality.find("VF") < strModality.length()) return VF;
00282 else if ( strModality.find("XA") < strModality.length()) return XA;
00283 else if ( strModality.find("XC") < strModality.length()) return XC;
00284
00285 else
00286 {
00289 return Unknow;
00290 }
00291 }
00292
00293 return Unknow;
00294 }
00295
00301 int File::GetXSize()
00302 {
00303 const std::string &strSize = GetEntryValue(0x0028,0x0011);
00304 if ( strSize == GDCM_UNFOUND )
00305 {
00306 return 0;
00307 }
00308
00309 return atoi( strSize.c_str() );
00310 }
00311
00318 int File::GetYSize()
00319 {
00320 const std::string &strSize = GetEntryValue(0x0028,0x0010);
00321 if ( strSize != GDCM_UNFOUND )
00322 {
00323 return atoi( strSize.c_str() );
00324 }
00325 if ( IsDicomV3() )
00326 {
00327 return 0;
00328 }
00329
00330
00331
00332 return 1;
00333 }
00334
00343 int File::GetZSize()
00344 {
00345
00346
00347 const std::string &strSize = GetEntryValue(0x0028,0x0008);
00348 if ( strSize != GDCM_UNFOUND )
00349 {
00350 return atoi( strSize.c_str() );
00351 }
00352
00353
00354 const std::string &strSize2 = GetEntryValue(0x0028,0x0012);
00355 if ( strSize2 != GDCM_UNFOUND )
00356 {
00357 return atoi( strSize2.c_str() );
00358 }
00359
00360 return 1;
00361 }
00362
00368 float File::GetXSpacing()
00369 {
00370 float xspacing = 1.0;
00371 float yspacing = 1.0;
00372 const std::string &strSpacing = GetEntryValue(0x0028,0x0030);
00373
00374 if( strSpacing == GDCM_UNFOUND )
00375 {
00376 gdcmWarningMacro( "Unfound Pixel Spacing (0028,0030)" );
00377 return 1.;
00378 }
00379
00380 int nbValues;
00381 if( ( nbValues = sscanf( strSpacing.c_str(),
00382 "%f\\%f", &yspacing, &xspacing)) != 2 )
00383 {
00384
00385 if( nbValues == 0 )
00386 xspacing = 1.0;
00387
00388 if( nbValues == 1 )
00389 xspacing = yspacing;
00390
00391 if ( xspacing == 0.0 )
00392 xspacing = 1.0;
00393
00394 return xspacing;
00395
00396 }
00397
00398
00399 if ( xspacing == 0. && yspacing == 0.)
00400 return 1.;
00401
00402 if ( xspacing == 0.)
00403 {
00404 gdcmWarningMacro("gdcmData/CT-MONO2-8-abdo.dcm problem");
00405
00406 nbValues = sscanf( strSpacing.c_str(), "%f\\0\\%f", &yspacing, &xspacing);
00407 gdcmAssertMacro( nbValues == 2 );
00408 }
00409
00410 return xspacing;
00411 }
00412
00418 float File::GetYSpacing()
00419 {
00420 float yspacing = 1.;
00421 std::string strSpacing = GetEntryValue(0x0028,0x0030);
00422
00423 if ( strSpacing == GDCM_UNFOUND )
00424 {
00425 gdcmWarningMacro("Unfound Pixel Spacing (0028,0030)");
00426 return 1.;
00427 }
00428
00429
00430 int nbValues = sscanf( strSpacing.c_str(), "%f", &yspacing);
00431
00432
00433 if( nbValues == 0 )
00434 yspacing = 1.0;
00435
00436 if ( yspacing == 0.0 )
00437 yspacing = 1.0;
00438
00439 return yspacing;
00440 }
00441
00448 float File::GetZSpacing()
00449 {
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460 const std::string &strSpacingBSlices = GetEntryValue(0x0018,0x0088);
00461
00462 if ( strSpacingBSlices == GDCM_UNFOUND )
00463 {
00464 gdcmWarningMacro("Unfound Spacing Between Slices (0018,0088)");
00465 const std::string &strSliceThickness = GetEntryValue(0x0018,0x0050);
00466 if ( strSliceThickness == GDCM_UNFOUND )
00467 {
00468 gdcmWarningMacro("Unfound Slice Thickness (0018,0050)");
00469 return 1.;
00470 }
00471 else
00472 {
00473
00474
00475
00476
00477 return (float)atof( strSliceThickness.c_str() );
00478 }
00479 }
00480
00481 return (float)atof( strSpacingBSlices.c_str() );
00482 }
00483
00490 float File::GetXOrigin()
00491 {
00492 float xImPos, yImPos, zImPos;
00493 std::string strImPos = GetEntryValue(0x0020,0x0032);
00494
00495 if ( strImPos == GDCM_UNFOUND )
00496 {
00497 gdcmWarningMacro( "Unfound Image Position Patient (0020,0032)");
00498 strImPos = GetEntryValue(0x0020,0x0030);
00499 if ( strImPos == GDCM_UNFOUND )
00500 {
00501 gdcmWarningMacro( "Unfound Image Position (RET) (0020,0030)");
00502 return 0.;
00503 }
00504 }
00505
00506 if( sscanf( strImPos.c_str(), "%f\\%f\\%f", &xImPos, &yImPos, &zImPos) != 3 )
00507 {
00508 return 0.;
00509 }
00510
00511 return xImPos;
00512 }
00513
00520 float File::GetYOrigin()
00521 {
00522 float xImPos, yImPos, zImPos;
00523 std::string strImPos = GetEntryValue(0x0020,0x0032);
00524
00525 if ( strImPos == GDCM_UNFOUND)
00526 {
00527 gdcmWarningMacro( "Unfound Image Position Patient (0020,0032)");
00528 strImPos = GetEntryValue(0x0020,0x0030);
00529 if ( strImPos == GDCM_UNFOUND )
00530 {
00531 gdcmWarningMacro( "Unfound Image Position (RET) (0020,0030)");
00532 return 0.;
00533 }
00534 }
00535
00536 if( sscanf( strImPos.c_str(), "%f\\%f\\%f", &xImPos, &yImPos, &zImPos) != 3 )
00537 {
00538 return 0.;
00539 }
00540
00541 return yImPos;
00542 }
00543
00552 float File::GetZOrigin()
00553 {
00554 float xImPos, yImPos, zImPos;
00555 std::string strImPos = GetEntryValue(0x0020,0x0032);
00556
00557 if ( strImPos != GDCM_UNFOUND )
00558 {
00559 if( sscanf( strImPos.c_str(), "%f\\%f\\%f", &xImPos, &yImPos, &zImPos) != 3)
00560 {
00561 gdcmWarningMacro( "Wrong Image Position Patient (0020,0032)");
00562 return 0.;
00563 }
00564 else
00565 {
00566 return zImPos;
00567 }
00568 }
00569
00570 strImPos = GetEntryValue(0x0020,0x0030);
00571 if ( strImPos != GDCM_UNFOUND )
00572 {
00573 if( sscanf( strImPos.c_str(),
00574 "%f\\%f\\%f", &xImPos, &yImPos, &zImPos ) != 3 )
00575 {
00576 gdcmWarningMacro( "Wrong Image Position (RET) (0020,0030)");
00577 return 0.;
00578 }
00579 else
00580 {
00581 return zImPos;
00582 }
00583 }
00584
00585 std::string strSliceLocation = GetEntryValue(0x0020,0x1041);
00586 if ( strSliceLocation != GDCM_UNFOUND )
00587 {
00588 if( sscanf( strSliceLocation.c_str(), "%f", &zImPos) != 1)
00589 {
00590 gdcmWarningMacro( "Wrong Slice Location (0020,1041)");
00591 return 0.;
00592 }
00593 else
00594 {
00595 return zImPos;
00596 }
00597 }
00598 gdcmWarningMacro( "Unfound Slice Location (0020,1041)");
00599
00600 std::string strLocation = GetEntryValue(0x0020,0x0050);
00601 if ( strLocation != GDCM_UNFOUND )
00602 {
00603 if( sscanf( strLocation.c_str(), "%f", &zImPos) != 1)
00604 {
00605 gdcmWarningMacro( "Wrong Location (0020,0050)");
00606 return 0.;
00607 }
00608 else
00609 {
00610 return zImPos;
00611 }
00612 }
00613 gdcmWarningMacro( "Unfound Location (0020,0050)");
00614
00615 return 0.;
00616 }
00617
00624 void File::GetImageOrientationPatient( float iop[6] )
00625 {
00626 std::string strImOriPat;
00627
00628 iop[0] = iop[1] = iop[2] = iop[3] = iop[4] = iop[5] = 0.;
00629
00630
00631 if ( (strImOriPat = GetEntryValue(0x0020,0x0037)) != GDCM_UNFOUND )
00632 {
00633 if( sscanf( strImOriPat.c_str(), "%f\\%f\\%f\\%f\\%f\\%f",
00634 &iop[0], &iop[1], &iop[2], &iop[3], &iop[4], &iop[5]) != 6 )
00635 {
00636 gdcmWarningMacro( "Wrong Image Orientation Patient (0020,0037). Less than 6 values were found." );
00637 }
00638 }
00639
00640
00641 else if ( (strImOriPat = GetEntryValue(0x0020,0x0035)) != GDCM_UNFOUND )
00642 {
00643 if( sscanf( strImOriPat.c_str(), "%f\\%f\\%f\\%f\\%f\\%f",
00644 &iop[0], &iop[1], &iop[2], &iop[3], &iop[4], &iop[5]) != 6 )
00645 {
00646 gdcmWarningMacro( "wrong Image Orientation Patient (0020,0035). Less than 6 values were found." );
00647 }
00648 }
00649 }
00650
00657 int File::GetBitsStored()
00658 {
00659 std::string strSize = GetEntryValue( 0x0028, 0x0101 );
00660 if ( strSize == GDCM_UNFOUND )
00661 {
00662 gdcmWarningMacro("(0028,0101) is supposed to be mandatory");
00663 return 0;
00664
00665 }
00666 return atoi( strSize.c_str() );
00667 }
00668
00675 int File::GetBitsAllocated()
00676 {
00677 std::string strSize = GetEntryValue(0x0028,0x0100);
00678 if ( strSize == GDCM_UNFOUND )
00679 {
00680 gdcmWarningMacro( "(0028,0100) is supposed to be mandatory");
00681 return 0;
00682
00683 }
00684 return atoi( strSize.c_str() );
00685 }
00686
00693 int File::GetHighBitPosition()
00694 {
00695 std::string strSize = GetEntryValue( 0x0028, 0x0102 );
00696 if ( strSize == GDCM_UNFOUND )
00697 {
00698 gdcmWarningMacro( "(0028,0102) is supposed to be mandatory");
00699 return 0;
00700 }
00701 return atoi( strSize.c_str() );
00702 }
00703
00710 int File::GetSamplesPerPixel()
00711 {
00712 const std::string &strSize = GetEntryValue(0x0028,0x0002);
00713 if ( strSize == GDCM_UNFOUND )
00714 {
00715 gdcmWarningMacro( "(0028,0002) is supposed to be mandatory");
00716 return 1;
00717
00718 }
00719 return atoi( strSize.c_str() );
00720 }
00721
00727 int File::GetPlanarConfiguration()
00728 {
00729 std::string strSize = GetEntryValue(0x0028,0x0006);
00730 if ( strSize == GDCM_UNFOUND )
00731 {
00732 gdcmWarningMacro( "Not found : Planar Configuration (0028,0006)");
00733 return 0;
00734 }
00735 return atoi( strSize.c_str() );
00736 }
00737
00743 int File::GetPixelSize()
00744 {
00745
00746
00747
00748
00749
00750 std::string pixelType = GetPixelType();
00751 if ( pixelType == "8U" || pixelType == "8S" )
00752 {
00753 return 1;
00754 }
00755 if ( pixelType == "16U" || pixelType == "16S")
00756 {
00757 return 2;
00758 }
00759 if ( pixelType == "32U" || pixelType == "32S")
00760 {
00761 return 4;
00762 }
00763 if ( pixelType == "FD" )
00764 {
00765 return 8;
00766 }
00767 gdcmWarningMacro( "Unknown pixel type");
00768 return 0;
00769 }
00770
00785 std::string File::GetPixelType()
00786 {
00787 std::string bitsAlloc = GetEntryValue(0x0028, 0x0100);
00788 if ( bitsAlloc == GDCM_UNFOUND )
00789 {
00790 gdcmWarningMacro( "Missing Bits Allocated (0028,0100)");
00791 bitsAlloc = "16";
00792 }
00793
00794 if ( bitsAlloc == "64" )
00795 {
00796 return "FD";
00797 }
00798 else if ( bitsAlloc == "12" )
00799 {
00800
00801 bitsAlloc = "16";
00802 }
00803 else if ( bitsAlloc == "24" )
00804 {
00805
00806 bitsAlloc = "8";
00807 }
00808
00809 std::string sign = GetEntryValue(0x0028, 0x0103);
00810
00811 if (sign == GDCM_UNFOUND )
00812 {
00813 gdcmWarningMacro( "Missing Pixel Representation (0028,0103)");
00814 sign = "U";
00815 }
00816 else if ( sign == "0" )
00817 {
00818 sign = "U";
00819 }
00820 else
00821 {
00822 sign = "S";
00823 }
00824 return bitsAlloc + sign;
00825 }
00826
00833 bool File::IsSignedPixelData()
00834 {
00835 std::string strSize = GetEntryValue( 0x0028, 0x0103 );
00836 if ( strSize == GDCM_UNFOUND )
00837 {
00838 gdcmWarningMacro( "(0028,0103) is supposed to be mandatory");
00839 return false;
00840 }
00841 int sign = atoi( strSize.c_str() );
00842 if ( sign == 0 )
00843 {
00844 return false;
00845 }
00846 return true;
00847 }
00848
00854 bool File::IsMonochrome()
00855 {
00856 const std::string &PhotometricInterp = GetEntryValue( 0x0028, 0x0004 );
00857 if ( Util::DicomStringEqual(PhotometricInterp, "MONOCHROME1")
00858 || Util::DicomStringEqual(PhotometricInterp, "MONOCHROME2") )
00859 {
00860 return true;
00861 }
00862 if ( PhotometricInterp == GDCM_UNFOUND )
00863 {
00864 gdcmWarningMacro( "Not found : Photometric Interpretation (0028,0004)");
00865 }
00866 return false;
00867 }
00868
00874 bool File::IsPaletteColor()
00875 {
00876 std::string PhotometricInterp = GetEntryValue( 0x0028, 0x0004 );
00877 if ( PhotometricInterp == "PALETTE COLOR " )
00878 {
00879 return true;
00880 }
00881 if ( PhotometricInterp == GDCM_UNFOUND )
00882 {
00883 gdcmWarningMacro( "Not found : Palette color (0028,0004)");
00884 }
00885 return false;
00886 }
00887
00893 bool File::IsYBRFull()
00894 {
00895 std::string PhotometricInterp = GetEntryValue( 0x0028, 0x0004 );
00896 if ( PhotometricInterp == "YBR_FULL" )
00897 {
00898 return true;
00899 }
00900 if ( PhotometricInterp == GDCM_UNFOUND )
00901 {
00902 gdcmWarningMacro( "Not found : YBR Full (0028,0004)");
00903 }
00904 return false;
00905 }
00906
00915 bool File::HasLUT()
00916 {
00917
00918
00919 if ( !GetDocEntry(0x0028,0x1101) )
00920 {
00921 return false;
00922 }
00923
00924 if ( !GetDocEntry(0x0028,0x1102) )
00925 {
00926 return false;
00927 }
00928
00929 if ( !GetDocEntry(0x0028,0x1103) )
00930 {
00931 return false;
00932 }
00933
00934 if ( !GetDocEntry(0x0028,0x1201) )
00935 {
00936 return false;
00937 }
00938
00939 if ( !GetDocEntry(0x0028,0x1202) )
00940 {
00941 return false;
00942 }
00943
00944 if ( !GetDocEntry(0x0028,0x1203) )
00945 {
00946 return false;
00947 }
00948
00949
00950
00951 return true;
00952 }
00953
00961 int File::GetLUTNbits()
00962 {
00963 std::vector<std::string> tokens;
00964 int lutNbits;
00965
00966
00967
00968
00969 std::string lutDescription = GetEntryValue(0x0028,0x1101);
00970 if ( lutDescription == GDCM_UNFOUND )
00971 {
00972 return 0;
00973 }
00974
00975 tokens.clear();
00976 Util::Tokenize ( lutDescription, tokens, "\\" );
00977
00978
00979
00980 lutNbits = atoi( tokens[2].c_str() );
00981 tokens.clear();
00982
00983 return lutNbits;
00984 }
00985
00990 float File::GetRescaleIntercept()
00991 {
00992 float resInter = 0.;
00994 const std::string &strRescInter = GetEntryValue(0x0028,0x1052);
00995 if ( strRescInter != GDCM_UNFOUND )
00996 {
00997 if( sscanf( strRescInter.c_str(), "%f", &resInter) != 1 )
00998 {
00999
01000 gdcmWarningMacro( "Rescale Intercept (0028,1052) is empty." );
01001 }
01002 }
01003
01004 return resInter;
01005 }
01006
01011 float File::GetRescaleSlope()
01012 {
01013 float resSlope = 1.;
01014
01015 std::string strRescSlope = GetEntryValue(0x0028,0x1053);
01016 if ( strRescSlope != GDCM_UNFOUND )
01017 {
01018 if( sscanf( strRescSlope.c_str(), "%f", &resSlope) != 1)
01019 {
01020
01021 gdcmWarningMacro( "Rescale Slope (0028,1053) is empty.");
01022 }
01023 }
01024
01025 return resSlope;
01026 }
01027
01035 int File::GetNumberOfScalarComponents()
01036 {
01037 if ( GetSamplesPerPixel() == 3 )
01038 {
01039 return 3;
01040 }
01041
01042
01043
01044 if ( GetEntryValue(0x0028,0x0100) == "24" )
01045 {
01046 return 3;
01047 }
01048
01049 std::string strPhotometricInterpretation = GetEntryValue(0x0028,0x0004);
01050
01051 if ( ( strPhotometricInterpretation == "PALETTE COLOR ") )
01052 {
01053 if ( HasLUT() )
01054 {
01055 return 3;
01056 }
01057 else
01058 {
01059 return 1;
01060 }
01061 }
01062
01063
01064
01065 if ( strPhotometricInterpretation == GDCM_UNFOUND ||
01066 Util::DicomStringEqual(strPhotometricInterpretation, "MONOCHROME1") ||
01067 Util::DicomStringEqual(strPhotometricInterpretation, "MONOCHROME2") )
01068 {
01069 return 1;
01070 }
01071 else
01072 {
01073
01074 return 3;
01075 }
01076 }
01077
01085 int File::GetNumberOfScalarComponentsRaw()
01086 {
01087
01088
01089 if ( File::GetEntryValue(0x0028,0x0100) == "24" )
01090 {
01091 return 3;
01092 }
01093
01094
01095 return GetSamplesPerPixel();
01096 }
01097
01103 size_t File::GetPixelOffset()
01104 {
01105 DocEntry *pxlElement = GetDocEntry(GrPixel, NumPixel);
01106 if ( pxlElement )
01107 {
01108 return pxlElement->GetOffset();
01109 }
01110 else
01111 {
01112 gdcmDebugMacro( "Big trouble : Pixel Element ("
01113 << std::hex << GrPixel<<","<< NumPixel<< ") NOT found" );
01114 return 0;
01115 }
01116 }
01117
01125 size_t File::GetPixelAreaLength()
01126 {
01127 DocEntry *pxlElement = GetDocEntry(GrPixel, NumPixel);
01128 if ( pxlElement )
01129 {
01130 return pxlElement->GetLength();
01131 }
01132 else
01133 {
01134 gdcmDebugMacro( "Big trouble : Pixel Element ("
01135 << std::hex << GrPixel<<","<< NumPixel<< ") NOT found" );
01136 return 0;
01137 }
01138 }
01139
01144 void File::AddAnonymizeElement (uint16_t group, uint16_t elem,
01145 std::string const &value)
01146
01147 {
01148 Element el;
01149 el.Group = group;
01150 el.Elem = elem;
01151 el.Value = value;
01152 AnonymizeList.push_back(el);
01153 }
01154
01159 void File::AnonymizeNoLoad()
01160 {
01161 std::fstream *fp = new std::fstream(Filename.c_str(),
01162 std::ios::in | std::ios::out | std::ios::binary);
01163
01164
01165
01166
01167
01168 gdcm::DocEntry *d;
01169 uint32_t offset;
01170 uint32_t lgth;
01171 uint32_t valLgth;
01172 std::string *spaces;
01173 for (ListElements::iterator it = AnonymizeList.begin();
01174 it != AnonymizeList.end();
01175 ++it)
01176 {
01177 d = GetDocEntry( (*it).Group, (*it).Elem);
01178
01179 if ( d == NULL)
01180 continue;
01181
01182 if ( dynamic_cast<BinEntry *>(d)
01183 || dynamic_cast<SeqEntry *>(d) )
01184 continue;
01185
01186 offset = d->GetOffset();
01187 lgth = d->GetLength();
01188 if (valLgth < lgth)
01189 {
01190 spaces = new std::string( lgth-valLgth, ' ');
01191 (*it).Value = (*it).Value + *spaces;
01192 delete spaces;
01193 }
01194 fp->seekp( offset, std::ios::beg );
01195 fp->write( (*it).Value.c_str(), lgth );
01196
01197 }
01198 fp->close();
01199 delete fp;
01200 }
01201
01206 bool File::AnonymizeFile()
01207 {
01208
01209 if ( AnonymizeList.begin() == AnonymizeList.end() )
01210 {
01211
01212 SetValEntry (" ",0x0010, 0x2154);
01213 SetValEntry (" ",0x0010, 0x1040);
01214 SetValEntry (" ",0x0010, 0x0020);
01215
01216 DocEntry* patientNameHE = GetDocEntry (0x0010, 0x0010);
01217
01218 if ( patientNameHE )
01219 {
01220 std::string studyInstanceUID = GetEntryValue (0x0020, 0x000d);
01221 if ( studyInstanceUID != GDCM_UNFOUND )
01222 {
01223 SetValEntry(studyInstanceUID, 0x0010, 0x0010);
01224 }
01225 else
01226 {
01227 SetValEntry("anonymised", 0x0010, 0x0010);
01228 }
01229 }
01230 }
01231 else
01232 {
01233 gdcm::DocEntry *d;
01234 for (ListElements::iterator it = AnonymizeList.begin();
01235 it != AnonymizeList.end();
01236 ++it)
01237 {
01238 d = GetDocEntry( (*it).Group, (*it).Elem);
01239
01240 if ( d == NULL)
01241 continue;
01242
01243 if ( dynamic_cast<BinEntry *>(d)
01244 || dynamic_cast<SeqEntry *>(d) )
01245 continue;
01246
01247 SetValEntry ((*it).Value, (*it).Group, (*it).Elem);
01248 }
01249 }
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303 return true;
01304 }
01305
01314 bool File::Write(std::string fileName, FileType filetype)
01315 {
01316 std::ofstream *fp = new std::ofstream(fileName.c_str(),
01317 std::ios::out | std::ios::binary);
01318 if (*fp == NULL)
01319 {
01320 gdcmWarningMacro("Failed to open (write) File: " << fileName.c_str());
01321 return false;
01322 }
01323
01324
01325 ValEntry *e0002 = GetValEntry(0x0002,0x0000);
01326 if( e0002 )
01327 {
01328 std::ostringstream sLen;
01329 sLen << ComputeGroup0002Length(filetype);
01330 e0002->SetValue(sLen.str());
01331 }
01332
01333
01334 if ( GetEntryValue(0x0028,0x0100) == "12")
01335 {
01336 SetValEntry("16", 0x0028,0x0100);
01337 }
01338
01339 int i_lgPix = GetEntryLength(GrPixel, NumPixel);
01340 if (i_lgPix != -2)
01341 {
01342
01343 std::string s_lgPix = Util::Format("%d", i_lgPix+12);
01344 s_lgPix = Util::DicomString( s_lgPix.c_str() );
01345 InsertValEntry(s_lgPix,GrPixel, 0x0000);
01346 }
01347
01348
01349
01350
01351
01352 if ( GetEntryValue(0x0028,0x0002).c_str()[0] == '3' )
01353 {
01354
01355
01356
01357
01358 DocEntry *e = GetDocEntry(0x0028,0x01101);
01359 if (e)
01360 {
01361 RemoveEntryNoDestroy(e);
01362 }
01363 e = GetDocEntry(0x0028,0x1102);
01364 if (e)
01365 {
01366 RemoveEntryNoDestroy(e);
01367 }
01368 e = GetDocEntry(0x0028,0x1103);
01369 if (e)
01370 {
01371 RemoveEntryNoDestroy(e);
01372 }
01373 e = GetDocEntry(0x0028,0x01201);
01374 if (e)
01375 {
01376 RemoveEntryNoDestroy(e);
01377 }
01378 e = GetDocEntry(0x0028,0x1202);
01379 if (e)
01380 {
01381 RemoveEntryNoDestroy(e);
01382 }
01383 e = GetDocEntry(0x0028,0x1203);
01384 if (e)
01385 {
01386 RemoveEntryNoDestroy(e);
01387 }
01388 }
01389
01390 Document::WriteContent(fp, filetype);
01391
01392 fp->close();
01393 delete fp;
01394
01395 return true;
01396 }
01397
01398
01399
01406 void File::InitializeDefaultFile()
01407 {
01408 std::string date = Util::GetCurrentDate();
01409 std::string time = Util::GetCurrentTime();
01410 std::string uid = Util::CreateUniqueUID();
01411 std::string uidMedia = uid;
01412 std::string uidInst = uid;
01413 std::string uidClass = Util::CreateUniqueUID();
01414 std::string uidStudy = Util::CreateUniqueUID();
01415 std::string uidSerie = Util::CreateUniqueUID();
01416
01417
01418 InsertValEntry("146 ", 0x0002, 0x0000);
01419
01420 InsertValEntry("1.2.840.10008.5.1.4.1.1.2", 0x0002, 0x0002);
01421
01422 InsertValEntry(uidMedia.c_str(), 0x0002, 0x0003);
01423
01424 InsertValEntry("1.2.840.10008.1.2.1 ", 0x0002, 0x0010);
01425
01426 InsertValEntry(uidClass.c_str(), 0x0002, 0x0012);
01427
01428 InsertValEntry("GDCM", 0x0002, 0x0016);
01429
01430
01431 InsertValEntry(date.c_str(), 0x0008, 0x0012);
01432
01433 InsertValEntry(time.c_str(), 0x0008, 0x0013);
01434
01435 InsertValEntry("1.2.840.10008.5.1.4.1.1.2", 0x0008, 0x0016);
01436
01437 InsertValEntry(uidInst.c_str(), 0x0008, 0x0018);
01438
01439 InsertValEntry("CT", 0x0008, 0x0060);
01440
01441 InsertValEntry("GDCM", 0x0008, 0x0070);
01442
01443 InsertValEntry("GDCM", 0x0008, 0x0080);
01444
01445 InsertValEntry("http://www-creatis.insa-lyon.fr/Public/Gdcm", 0x0008, 0x0081);
01446
01447
01448 InsertValEntry("GDCM", 0x0010, 0x0010);
01449
01450 InsertValEntry("GDCMID", 0x0010, 0x0020);
01451
01452
01453 InsertValEntry(uidStudy.c_str(), 0x0020, 0x000d);
01454
01455 InsertValEntry(uidSerie.c_str(), 0x0020, 0x000e);
01456
01457 InsertValEntry("1", 0x0020, 0x0010);
01458
01459 InsertValEntry("1", 0x0020, 0x0011);
01460
01461
01462 InsertValEntry("1", 0x0028, 0x0002);
01463
01464 InsertValEntry("MONOCHROME1", 0x0028, 0x0004);
01465
01466 InsertValEntry("0", 0x0028, 0x0010);
01467
01468 InsertValEntry("0", 0x0028, 0x0011);
01469
01470 InsertValEntry("8", 0x0028, 0x0100);
01471
01472 InsertValEntry("8", 0x0028, 0x0101);
01473
01474 InsertValEntry("7", 0x0028, 0x0102);
01475
01476 InsertValEntry("0", 0x0028, 0x0103);
01477
01478
01479
01480 GrPixel = 0x7fe0;
01481 NumPixel = 0x0010;
01482 InsertBinEntry(0, 0, GrPixel, NumPixel);
01483 }
01484
01485
01486
01492 void File::ComputeRLEInfo()
01493 {
01494 std::string ts = GetTransferSyntax();
01495 if ( !Global::GetTS()->IsRLELossless(ts) )
01496 {
01497 return;
01498 }
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513 ReadAndSkipEncapsulatedBasicOffsetTable();
01514
01515
01516
01517
01518
01519
01520
01521
01522 long frameLength;
01523 while ( (frameLength = ReadTagLength(0xfffe, 0xe000)) )
01524 {
01525
01526
01527
01528
01529 long frameOffset = Fp->tellg();
01530
01531 uint32_t nbRleSegments = ReadInt32();
01532 if ( nbRleSegments > 16 )
01533 {
01534
01535 gdcmWarningMacro( "Too many segments.");
01536 }
01537
01538 uint32_t rleSegmentOffsetTable[16];
01539 for( int k = 1; k <= 15; k++ )
01540 {
01541 rleSegmentOffsetTable[k] = ReadInt32();
01542 }
01543
01544
01545
01546
01547 long rleSegmentLength[15];
01548
01549 if ( nbRleSegments > 1)
01550 {
01551 for(unsigned int k = 1; k <= nbRleSegments-1; k++)
01552 {
01553 rleSegmentLength[k] = rleSegmentOffsetTable[k+1]
01554 - rleSegmentOffsetTable[k];
01555 SkipBytes(rleSegmentLength[k]);
01556 }
01557 }
01558
01559 rleSegmentLength[nbRleSegments] = frameLength
01560 - rleSegmentOffsetTable[nbRleSegments];
01561 SkipBytes(rleSegmentLength[nbRleSegments]);
01562
01563
01564 RLEFrame *newFrame = new RLEFrame;
01565 newFrame->SetNumberOfFragments(nbRleSegments);
01566 for( unsigned int uk = 1; uk <= nbRleSegments; uk++ )
01567 {
01568 newFrame->SetOffset(uk,frameOffset + rleSegmentOffsetTable[uk]);
01569 newFrame->SetLength(uk,rleSegmentLength[uk]);
01570 }
01571 RLEInfo->AddFrame(newFrame);
01572 }
01573
01574
01575
01576 if ( !ReadTag(0xfffe, 0xe0dd) )
01577 {
01578 gdcmWarningMacro( "No sequence delimiter item at end of RLE item sequence");
01579 }
01580 }
01581
01588 void File::ComputeJPEGFragmentInfo()
01589 {
01590
01591 std::string ts = GetTransferSyntax();
01592 if ( ! Global::GetTS()->IsJPEG(ts) )
01593 {
01594 return;
01595 }
01596
01597 ReadAndSkipEncapsulatedBasicOffsetTable();
01598
01599
01600
01601 long fragmentLength;
01602 while ( (fragmentLength = ReadTagLength(0xfffe, 0xe000)) )
01603 {
01604 long fragmentOffset = Fp->tellg();
01605
01606
01607 JPEGFragment *newFragment = new JPEGFragment;
01608 newFragment->SetOffset(fragmentOffset);
01609 newFragment->SetLength(fragmentLength);
01610 JPEGInfo->AddFragment(newFragment);
01611
01612 SkipBytes(fragmentLength);
01613 }
01614
01615
01616
01617 if ( !ReadTag(0xfffe, 0xe0dd) )
01618 {
01619 gdcmWarningMacro( "No sequence delimiter item at end of JPEG item sequence");
01620 }
01621 }
01622
01636 bool File::ReadTag(uint16_t testGroup, uint16_t testElement)
01637 {
01638 long positionOnEntry = Fp->tellg();
01639 long currentPosition = Fp->tellg();
01640
01641
01642
01643 uint16_t itemTagGroup;
01644 uint16_t itemTagElement;
01645 try
01646 {
01647 itemTagGroup = ReadInt16();
01648 itemTagElement = ReadInt16();
01649 }
01650 catch ( FormatError e )
01651 {
01652
01653 return false;
01654 }
01655 if ( itemTagGroup != testGroup || itemTagElement != testElement )
01656 {
01657 gdcmWarningMacro( "Wrong Item Tag found:"
01658 << " We should have found tag ("
01659 << std::hex << testGroup << "," << testElement << ")" << std::endl
01660 << " but instead we encountered tag ("
01661 << std::hex << itemTagGroup << "," << itemTagElement << ")"
01662 << " at address: " << " 0x(" << (unsigned int)currentPosition << ")"
01663 ) ;
01664 Fp->seekg(positionOnEntry, std::ios::beg);
01665
01666 return false;
01667 }
01668 return true;
01669 }
01670
01685 uint32_t File::ReadTagLength(uint16_t testGroup, uint16_t testElement)
01686 {
01687
01688 if ( !ReadTag(testGroup, testElement) )
01689 {
01690 return 0;
01691 }
01692
01694 long currentPosition = Fp->tellg();
01695 uint32_t itemLength = ReadInt32();
01696 {
01697 gdcmWarningMacro( "Basic Item Length is: "
01698 << itemLength << std::endl
01699 << " at address: " << std::hex << (unsigned int)currentPosition);
01700 }
01701 return itemLength;
01702 }
01703
01708 void File::ReadAndSkipEncapsulatedBasicOffsetTable()
01709 {
01711 uint32_t itemLength = ReadTagLength(0xfffe, 0xe000);
01712
01713
01714
01715
01716
01717
01718
01719 if ( itemLength != 0 )
01720 {
01721 char *basicOffsetTableItemValue = new char[itemLength + 1];
01722 Fp->read(basicOffsetTableItemValue, itemLength);
01723
01724 #ifdef GDCM_DEBUG
01725 for (unsigned int i=0; i < itemLength; i += 4 )
01726 {
01727 uint32_t individualLength = str2num( &basicOffsetTableItemValue[i],
01728 uint32_t);
01729 gdcmWarningMacro( "Read one length: " <<
01730 std::hex << individualLength );
01731 }
01732 #endif //GDCM_DEBUG
01733
01734 delete[] basicOffsetTableItemValue;
01735 }
01736 }
01737
01738
01739
01740
01741
01742 }