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
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090 #include "gdcmFile.h"
00091 #include "gdcmGlobal.h"
00092 #include "gdcmUtil.h"
00093 #include "gdcmDebug.h"
00094 #include "gdcmTS.h"
00095 #include "gdcmSeqEntry.h"
00096 #include "gdcmRLEFramesInfo.h"
00097 #include "gdcmJPEGFragmentsInfo.h"
00098 #include "gdcmDataEntry.h"
00099 #include "gdcmSQItem.h"
00100
00101 #include <vector>
00102 #include <stdio.h>
00103 #include <stdlib.h>
00104
00105 namespace GDCM_NAME_SPACE
00106 {
00107
00108
00109
00110
00114 File::File():
00115 Document()
00116 {
00117 RLEInfo = new RLEFramesInfo;
00118 JPEGInfo = new JPEGFragmentsInfo;
00119 GrPixel = 0x7fe0;
00120 NumPixel = 0x0010;
00121 BasicOffsetTableItemValue = 0;
00122 FourthDimensionLocation = TagKey(0,0);
00123 }
00124
00125
00129 File::~File()
00130 {
00131 if ( RLEInfo )
00132 delete RLEInfo;
00133 if ( JPEGInfo )
00134 delete JPEGInfo;
00135 delete[] BasicOffsetTableItemValue;
00136 }
00137
00138
00139
00145 bool File::Load( )
00146 {
00147 if ( ! this->Document::Load( ) )
00148 return false;
00149
00150 return DoTheLoadingJob( );
00151 }
00152
00158 bool File::DoTheLoadingJob( )
00159 {
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171 const std::string &imgLocation = GetEntryString(0x0028, 0x0200);
00172 if ( imgLocation == GDCM_UNFOUND )
00173 {
00174
00175 GrPixel = 0x7fe0;
00176 }
00177 else
00178 {
00179 GrPixel = (uint16_t) atoi( imgLocation.c_str() );
00180 }
00181
00182
00183
00184
00185 if ( GrPixel == 0xe07f )
00186 {
00187 GrPixel = 0x7fe0;
00188 }
00189
00190 if ( GrPixel != 0x7fe0 )
00191 {
00192
00193 NumPixel = 0x1010;
00194 }
00195 else
00196 {
00197 NumPixel = 0x0010;
00198 }
00199
00200
00201
00202
00203 DocEntry *entry = GetDocEntry(GrPixel, NumPixel);
00204 if ( entry != 0 )
00205 {
00206
00207 OpenFile();
00208 const std::string &ts = GetTransferSyntax();
00209 Fp->seekg( entry->GetOffset(), std::ios::beg );
00210 if ( Global::GetTS()->IsRLELossless(ts) )
00211 ComputeRLEInfo();
00212 else if ( Global::GetTS()->IsJPEG(ts) )
00213 ComputeJPEGFragmentInfo();
00214 CloseFile();
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253 VRKey PixelVR;
00254
00255
00256 if ( GetBitsAllocated() == 8 || GetBitsAllocated() == 24 )
00257 PixelVR = "OB";
00258 else
00259 PixelVR = "OW";
00260
00261 if ( PixelVR != entry->GetVR() )
00262 {
00263 entry->SetVR(PixelVR);
00264 }
00265 }
00266 return true;
00267 }
00268
00277 bool File::IsReadable()
00278 {
00279 if ( !Document::IsReadable() )
00280 {
00281 return false;
00282 }
00283
00284 const std::string &res = GetEntryString(0x0028, 0x0005);
00285 if ( res != GDCM_UNFOUND && atoi(res.c_str()) > 4 )
00286 {
00287 gdcmWarningMacro("Wrong Image Dimensions" << res);
00288 return false;
00289 }
00290 bool b0028_0100 = true;
00291 if ( !GetDocEntry(0x0028, 0x0100) )
00292 {
00293 gdcmWarningMacro("Bits Allocated (0028|0100) not found");
00294
00295 b0028_0100 = false;
00296 }
00297 bool b0028_0101 = true;
00298 if ( !GetDocEntry(0x0028, 0x0101) )
00299 {
00300 gdcmWarningMacro("Bits Stored (0028|0101) not found");
00301
00302 b0028_0101 = false;
00303 }
00304 bool b0028_0102 = true;
00305 if ( !GetDocEntry(0x0028, 0x0102) )
00306 {
00307 gdcmWarningMacro("Hight Bit (0028|0102) not found");
00308
00309 b0028_0102 = false;
00310 }
00311 bool b0028_0103 = true;
00312 if ( !GetDocEntry(0x0028, 0x0103) )
00313 {
00314 gdcmWarningMacro("Pixel Representation (0028|0103) not found");
00315
00316 b0028_0103 = false;
00317 }
00318
00319 if ( !b0028_0100 && !b0028_0101 && !b0028_0102 && !b0028_0103)
00320 {
00321 gdcmWarningMacro("Too much mandatory Tags missing !");
00322 return false;
00323 }
00324
00325 if ( !GetDocEntry(GrPixel, NumPixel) )
00326 {
00327 gdcmWarningMacro("Pixel Dicom Element " << std::hex <<
00328 GrPixel << "|" << NumPixel << "not found");
00329 return false;
00330 }
00331 return true;
00332 }
00333
00338 int File::GetImageNumber()
00339 {
00340
00341 std::string strImNumber = GetEntryString(0x0020,0x0013);
00342 if ( strImNumber != GDCM_UNFOUND )
00343 {
00344 return atoi( strImNumber.c_str() );
00345 }
00346 return 0;
00347 }
00348
00353 ModalityType File::GetModality()
00354 {
00355
00356 std::string strModality = GetEntryString(0x0008,0x0060);
00357 if ( strModality != GDCM_UNFOUND )
00358 {
00359 if ( strModality.find("AU") < strModality.length()) return AU;
00360 else if ( strModality.find("AS") < strModality.length()) return AS;
00361 else if ( strModality.find("BI") < strModality.length()) return BI;
00362 else if ( strModality.find("CF") < strModality.length()) return CF;
00363 else if ( strModality.find("CP") < strModality.length()) return CP;
00364 else if ( strModality.find("CR") < strModality.length()) return CR;
00365 else if ( strModality.find("CT") < strModality.length()) return CT;
00366 else if ( strModality.find("CS") < strModality.length()) return CS;
00367 else if ( strModality.find("DD") < strModality.length()) return DD;
00368 else if ( strModality.find("DF") < strModality.length()) return DF;
00369 else if ( strModality.find("DG") < strModality.length()) return DG;
00370 else if ( strModality.find("DM") < strModality.length()) return DM;
00371 else if ( strModality.find("DS") < strModality.length()) return DS;
00372 else if ( strModality.find("DX") < strModality.length()) return DX;
00373 else if ( strModality.find("ECG") < strModality.length()) return ECG;
00374 else if ( strModality.find("EPS") < strModality.length()) return EPS;
00375 else if ( strModality.find("FA") < strModality.length()) return FA;
00376 else if ( strModality.find("FS") < strModality.length()) return FS;
00377 else if ( strModality.find("HC") < strModality.length()) return HC;
00378 else if ( strModality.find("HD") < strModality.length()) return HD;
00379 else if ( strModality.find("LP") < strModality.length()) return LP;
00380 else if ( strModality.find("LS") < strModality.length()) return LS;
00381 else if ( strModality.find("MA") < strModality.length()) return MA;
00382 else if ( strModality.find("MR") < strModality.length()) return MR;
00383 else if ( strModality.find("NM") < strModality.length()) return NM;
00384 else if ( strModality.find("OT") < strModality.length()) return OT;
00385 else if ( strModality.find("PT") < strModality.length()) return PT;
00386 else if ( strModality.find("RF") < strModality.length()) return RF;
00387 else if ( strModality.find("RG") < strModality.length()) return RG;
00388 else if ( strModality.find("RTDOSE")
00389 < strModality.length()) return RTDOSE;
00390 else if ( strModality.find("RTIMAGE")
00391 < strModality.length()) return RTIMAGE;
00392 else if ( strModality.find("RTPLAN")
00393 < strModality.length()) return RTPLAN;
00394 else if ( strModality.find("RTSTRUCT")
00395 < strModality.length()) return RTSTRUCT;
00396 else if ( strModality.find("SM") < strModality.length()) return SM;
00397 else if ( strModality.find("ST") < strModality.length()) return ST;
00398 else if ( strModality.find("TG") < strModality.length()) return TG;
00399 else if ( strModality.find("US") < strModality.length()) return US;
00400 else if ( strModality.find("VF") < strModality.length()) return VF;
00401 else if ( strModality.find("XA") < strModality.length()) return XA;
00402 else if ( strModality.find("XC") < strModality.length()) return XC;
00403
00404 else
00405 {
00408 return Unknow;
00409 }
00410 }
00411 return Unknow;
00412 }
00413
00419 int File::GetXSize()
00420 {
00421 DataEntry *entry = GetDataEntry(0x0028,0x0011);
00422 if( entry )
00423 return (int)entry->GetValue(0);
00424 return 0;
00425 }
00426
00433 int File::GetYSize()
00434 {
00435 DataEntry *entry = GetDataEntry(0x0028,0x0010);
00436 if( entry )
00437 return (int)entry->GetValue(0);
00438
00439 if ( IsDicomV3() )
00440 {
00441 return 0;
00442 }
00443
00444
00445
00446
00447 return 1;
00448 }
00449
00458 int File::GetZSize()
00459 {
00460
00461
00462 DataEntry *entry = GetDataEntry(0x0028,0x0008);
00463 if( entry )
00464 return (int)entry->GetValue(0);
00465
00466
00467 entry = GetDataEntry(0x0028,0x0012);
00468 if( entry )
00469 return (int)entry->GetValue(0);
00470 return 1;
00471 }
00472
00473
00474
00475 bool File::GetSpacing(float &xspacing, float &yspacing, float &zspacing)
00476 {
00477 xspacing = yspacing = zspacing = 1.0;
00478 TS *ts = Global::GetTS();
00479 std::string sopclassuid_used;
00480
00481
00482
00483 const std::string &mediastoragesopclassuid_str = GetEntryString(0x0002,0x0002);
00484 const std::string &mediastoragesopclassuid = ts->GetValue(mediastoragesopclassuid_str);
00485
00486 const std::string &sopclassuid_str = GetEntryString(0x0008,0x0016);
00487 const std::string &sopclassuid = ts->GetValue(sopclassuid_str);
00488 if ( mediastoragesopclassuid == GDCM_UNFOUND && sopclassuid == GDCM_UNFOUND )
00489 {
00490 return false;
00491 }
00492 else
00493 {
00494 if( mediastoragesopclassuid == sopclassuid )
00495 {
00496 sopclassuid_used = mediastoragesopclassuid;
00497 }
00498 else
00499 {
00500 gdcmWarningMacro( "Inconsistant SOP Class UID: "
00501 << mediastoragesopclassuid << " and " << sopclassuid );
00502 return false;
00503 }
00504 }
00505
00506 if( sopclassuid_used == "Enhanced MR Image Storage" )
00507 {
00508 SeqEntry *PerframeFunctionalGroupsSequence = GetSeqEntry(0x5200,0x9230);
00509 unsigned int n = PerframeFunctionalGroupsSequence->GetNumberOfSQItems();
00510 if( !n ) return false;
00511 SQItem *item1 = PerframeFunctionalGroupsSequence->GetFirstSQItem();
00512 DocEntry *p = item1->GetDocEntry(0x0028,0x9110);
00513 if( !p ) return false;
00514 SeqEntry *seq = dynamic_cast<SeqEntry*>(p);
00515 unsigned int n1 = seq->GetNumberOfSQItems();
00516 if( !n1 ) return false;
00517 SQItem *item2 = seq->GetFirstSQItem();
00518
00519 DocEntry *p2 = item2->GetDocEntry(0x0028,0x0030);
00520 if( !p2 ) return false;
00521 DataEntry *entry = dynamic_cast<DataEntry *>(p2);
00522 std::string spacing = entry->GetString();
00523 if ( sscanf( spacing.c_str(), "%f\\%f", &yspacing, &xspacing) != 2 )
00524 {
00525 xspacing = yspacing = 1.;
00526 return false;
00527 }
00528
00529 DocEntry *p3 = item2->GetDocEntry(0x0018,0x0050);
00530 if( !p3 ) return false;
00531 DataEntry *entry2 = dynamic_cast<DataEntry *>(p3);
00532 std::string thickness = entry2->GetString();
00533 if ( sscanf( thickness.c_str(), "%f", &zspacing) != 1 )
00534 {
00535 zspacing = 1.;
00536 return false;
00537 }
00538 return true;
00539 }
00540 return false;
00541 }
00542
00551 int File::GetTSize()
00552 {
00553 if (FourthDimensionLocation == TagKey(0,0) )
00554 return 1;
00555
00556 DataEntry *entry = GetDataEntry(FourthDimensionLocation.GetGroup(),
00557 FourthDimensionLocation.GetElement() );
00558 if( !entry )
00559 {
00560 gdcmWarningMacro( " FourthDimensionLocation not found at : " <<
00561 std::hex << FourthDimensionLocation.GetGroup()
00562 << "|" << FourthDimensionLocation.GetElement());
00563 return 1;
00564 }
00565 else
00566 {
00567 return (int)entry->GetValue(0);
00568 }
00569 }
00570
00571
00572
00579 float File::GetXSpacing()
00580 {
00581 float xspacing = 1.0;
00582 float yspacing = 1.0;
00583 float zspacing = 1.0;
00584
00585 uint32_t nbValue;
00586 DataEntry *entry;
00587 bool ok = false;
00588 if ( GetSpacing(xspacing,yspacing,zspacing) )
00589 {
00590 return xspacing;
00591 }
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635 std::string SOPClassUID = GetEntryString(0x0008,0x0016);
00636
00639
00641
00642 if (Util::DicomStringEqual( SOPClassUID,"1.2.840.10008.5.1.4.1.1.6")
00643
00644 || Util::DicomStringEqual( SOPClassUID,"1.2.840.10008.5.1.4.1.1.6.1")
00645
00646 || Util::DicomStringEqual( SOPClassUID,"1.2.840.10008.5.1.4.1.1.3")
00647
00648 || Util::DicomStringEqual( SOPClassUID,"1.2.840.10008.5.1.4.1.1.3.1") )
00649
00650 {
00651
00652
00653
00654 entry = GetDataEntry(0x0028,0x0034);
00655 if ( entry )
00656 {
00657 nbValue = entry->GetValueCount();
00658 if( nbValue !=2 ) {
00659 gdcmWarningMacro("PixelAspectRatio (0x0028,0x0034) "
00660 << "has a wrong number of values :" << nbValue);
00661 }
00662 xspacing = 1.0;
00663 ok = true;
00664 }
00665
00666 if (ok)
00667 return xspacing;
00668 }
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680 entry = GetDataEntry(0x0018,0x1164);
00681 if( entry )
00682 {
00683 nbValue = entry->GetValueCount();
00684
00685 if( nbValue !=2 )
00686 gdcmWarningMacro("ImagerPixelSpacing (0x0018,0x1164) "
00687 << "has a wrong number of values :" << nbValue);
00688
00689 if( nbValue >= 3 )
00690 xspacing = (float)entry->GetValue(2);
00691 else if( nbValue >= 2 )
00692 xspacing = (float)entry->GetValue(1);
00693 else
00694 xspacing = (float)entry->GetValue(0);
00695
00696 if ( xspacing == 0.0 )
00697 xspacing = 1.0;
00698 return xspacing;
00699 }
00700 else
00701 {
00702 gdcmWarningMacro( "Unfound Imager Pixel Spacing (0018,1164)" );
00703 }
00704
00705 entry = GetDataEntry(0x0028,0x0030);
00706 if( entry )
00707 {
00708 nbValue = entry->GetValueCount();
00709 if( nbValue !=2 )
00710 gdcmWarningMacro("PixelSpacing (0x0018,0x0030) "
00711 << "has a wrong number of values :" << nbValue);
00712
00713 if( nbValue >= 3 )
00714 xspacing = (float)entry->GetValue(2);
00715 else if( nbValue >= 2 )
00716 xspacing = (float)entry->GetValue(1);
00717 else
00718 xspacing = (float)entry->GetValue(0);
00719
00720 if ( xspacing == 0.0 )
00721 xspacing = 1.0;
00722 return xspacing;
00723 }
00724 else
00725 {
00726 gdcmWarningMacro( "Unfound Pixel Spacing (0028,0030)" );
00727 }
00728 return xspacing;
00729 }
00730
00737 float File::GetYSpacing()
00738 {
00739 float xspacing = 1., yspacing = 1.0, zspacing = 1.;
00740 uint32_t nbValue;
00741 DataEntry *entry;
00742 bool ok = false;
00743 if ( GetSpacing(xspacing,yspacing,zspacing) )
00744 {
00745 return yspacing;
00746 }
00747
00748
00749 std::string SOPClassUID = GetEntryString(0x0008,0x0016);
00750
00753
00755
00756 if (Util::DicomStringEqual( SOPClassUID,"1.2.840.10008.5.1.4.1.1.6")
00757
00758 || Util::DicomStringEqual( SOPClassUID,"1.2.840.10008.5.1.4.1.1.6.1")
00759
00760 || Util::DicomStringEqual( SOPClassUID,"1.2.840.10008.5.1.4.1.1.3")
00761
00762 || Util::DicomStringEqual( SOPClassUID,"1.2.840.10008.5.1.4.1.1.3.1") )
00763
00764 {
00765
00766
00767
00768 entry = GetDataEntry(0x0028,0x0034);
00769 if ( entry )
00770 {
00771 nbValue = entry->GetValueCount();
00772 if( nbValue ==2 ) {
00773 yspacing = (float)entry->GetValue(0)/(float)entry->GetValue(1);
00774
00775 ok = true;
00776 }
00777 else
00778 {
00779 gdcmWarningMacro("PixelAspectRatio (0x0028,0x0034) "
00780 << "has a wrong number of values :" << nbValue);
00781 if (nbValue == 0 ) {
00782 ok = false;
00783 }
00784 else if (nbValue == 1 ) {
00785 yspacing = 1.0;
00786 ok = true;
00787 }
00788 }
00789 }
00790
00791 if (ok)
00792 return yspacing;
00793 }
00794
00795
00796
00797
00798 yspacing = 1.0;
00799
00800
00801 entry = GetDataEntry(0x0018,0x1164);
00802 if( entry )
00803 {
00804 yspacing = (float)entry->GetValue(0);
00805
00806 if ( yspacing == 0.0 )
00807 yspacing = 1.0;
00808 return yspacing;
00809 }
00810 else
00811 {
00812 gdcmWarningMacro( "Unfound Imager Pixel Spacing (0018,1164)" );
00813 }
00814
00815 entry = GetDataEntry(0x0028,0x0030);
00816 if( entry )
00817 {
00818 yspacing = (float)entry->GetValue(0);
00819
00820 if ( yspacing == 0.0 )
00821 yspacing = 1.0;
00822 return yspacing;
00823 }
00824 else
00825 {
00826 gdcmWarningMacro( "Unfound Pixel Spacing (0028,0030)" );
00827 }
00828
00829 return yspacing;
00830 }
00831
00845 float File::GetZSpacing()
00846 {
00847
00848 float xspacing = 1.0;
00849 float yspacing = 1.0;
00850 float zspacing = 1.0;
00851 if ( GetSpacing(xspacing,yspacing,zspacing) )
00852 {
00853 return zspacing;
00854 }
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865 DataEntry *entry = GetDataEntry(0x0018,0x0088);
00866 if( entry )
00867 { zspacing = (float)entry->GetValue(0);
00868
00869 if ( zspacing == 0.0 )
00870 zspacing = 1.0;
00871 return zspacing;
00872 }
00873 else
00874 gdcmWarningMacro("Unfound Spacing Between Slices (0018,0088)");
00875
00876
00877
00878
00879 entry = GetDataEntry(0x0018,0x0050);
00880 if( entry )
00881 {
00882 zspacing = (float)entry->GetValue(0);
00883
00884 if ( zspacing == 0.0 )
00885 zspacing = 1.0;
00886 return zspacing;
00887 }
00888 else
00889 gdcmWarningMacro("Unfound Slice Thickness (0018,0050)");
00890
00891
00892
00893
00894 entry = GetDataEntry(0x3004,0x000c);
00895 if( entry )
00896 {
00897 float z1 = (float)entry->GetValue(0);
00898 float z2 = (float)entry->GetValue(1);
00899 zspacing = z2 - z1;
00900
00901 if ( zspacing == 0.0 )
00902 zspacing = 1.0;
00903 return zspacing;
00904 }
00905
00906 return zspacing;
00907 }
00908
00915 float File::GetXOrigin()
00916 {
00917 DataEntry *entry = GetDataEntry(0x0020,0x0032);
00918 if( !entry )
00919 {
00920 gdcmWarningMacro( "Unfound Image Position Patient (0020,0032)");
00921 entry = GetDataEntry(0x0020,0x0030);
00922 if( !entry )
00923 {
00924 gdcmWarningMacro( "Unfound Image Position (RET) (0020,0030)");
00925 return 0.0f;
00926 }
00927 }
00928
00929 if( entry->GetValueCount() == 3 )
00930 {
00931 if (!entry->IsValueCountValid() )
00932 {
00933 gdcmErrorMacro( "Invalid Value Count" );
00934 }
00935 return (float)entry->GetValue(0);
00936 }
00937 return 0.0f;
00938 }
00939
00946 float File::GetYOrigin()
00947 {
00948 DataEntry *entry = GetDataEntry(0x0020,0x0032);
00949 if( !entry )
00950 {
00951 gdcmWarningMacro( "Unfound Image Position Patient (0020,0032)");
00952 entry = GetDataEntry(0x0020,0x0030);
00953 if( !entry )
00954 {
00955 gdcmWarningMacro( "Unfound Image Position (RET) (0020,0030)");
00956 return 0.0f;
00957 }
00958 }
00959
00960 if( entry->GetValueCount() == 3 )
00961 {
00962 if (!entry->IsValueCountValid() )
00963 {
00964 gdcmErrorMacro( "Invalid Value Count" );
00965 }
00966 return (float)entry->GetValue(1);
00967 }
00968 return 0.0f;
00969 }
00970
00979 float File::GetZOrigin()
00980 {
00981 DataEntry *entry = GetDataEntry(0x0020,0x0032);
00982 if( entry )
00983 {
00984 if( entry->GetValueCount() == 3 )
00985 {
00986 if (!entry->IsValueCountValid() )
00987 {
00988 gdcmErrorMacro( "Invalid Value Count" );
00989 }
00990 return (float)entry->GetValue(2);
00991 }
00992 gdcmWarningMacro( "Wrong Image Position Patient (0020,0032)");
00993 return 0.0f;
00994 }
00995
00996 entry = GetDataEntry(0x0020,0x0030);
00997 if( entry )
00998 {
00999 if( entry->GetValueCount() == 3 )
01000 {
01001 if (!entry->IsValueCountValid() )
01002 {
01003 gdcmErrorMacro( "Invalid Value Count" );
01004 }
01005 return (float)entry->GetValue(2);
01006 }
01007 gdcmWarningMacro( "Wrong Image Position (RET) (0020,0030)");
01008 return 0.0f;
01009 }
01010
01011
01012 entry = GetDataEntry(0x0020,0x1041);
01013 if( entry )
01014 {
01015 if( entry->GetValueCount() == 1 )
01016 {
01017 if (!entry->IsValueCountValid() )
01018 {
01019 gdcmErrorMacro( "Invalid Value Count" );
01020 }
01021 return (float)entry->GetValue(0);
01022 }
01023 gdcmWarningMacro( "Wrong Slice Location (0020,1041)");
01024 return 0.0f;
01025 }
01026
01027 entry = GetDataEntry(0x0020,0x0050);
01028 if( entry )
01029 {
01030 if( entry->GetValueCount() == 1 )
01031 {
01032 if (!entry->IsValueCountValid() )
01033 {
01034 gdcmErrorMacro( "Invalid Value Count" );
01035 }
01036 return (float)entry->GetValue(0);
01037 }
01038 gdcmWarningMacro( "Wrong Location (0020,0050)");
01039 return 0.0f;
01040 }
01041 return 0.;
01042 }
01043
01056 bool File::GetImageOrientationPatient( float iop[6] )
01057 {
01058 std::string strImOriPat;
01059
01060 iop[0] = iop[4] = 1.;
01061 iop[1] = iop[2] = iop[3] = iop[5] = 0.;
01062
01063
01064 if ( (strImOriPat = GetEntryString(0x0020,0x0037)) != GDCM_UNFOUND )
01065 {
01066 if ( sscanf( strImOriPat.c_str(), "%f \\ %f \\%f \\%f \\%f \\%f ",
01067 &iop[0], &iop[1], &iop[2], &iop[3], &iop[4], &iop[5]) != 6 )
01068 {
01069 gdcmWarningMacro( "Wrong Image Orientation Patient (0020,0037)."
01070 << " Less than 6 values were found." );
01071 return false;
01072 }
01073 return true;
01074 }
01075
01076
01077 else if ( (strImOriPat = GetEntryString(0x0020,0x0035)) != GDCM_UNFOUND )
01078 {
01079 if ( sscanf( strImOriPat.c_str(), "%f \\ %f \\%f \\%f \\%f \\%f ",
01080 &iop[0], &iop[1], &iop[2], &iop[3], &iop[4], &iop[5]) != 6 )
01081 {
01082 gdcmWarningMacro( "wrong Image Orientation Patient (0020,0035). "
01083 << "Less than 6 values were found." );
01084 return false;
01085 }
01086 return true;
01087 }
01088 return false;
01089 }
01090
01096 float File::GetXCosineOnX()
01097 {
01098 float iop[6];
01099 GetImageOrientationPatient( iop );
01100 return(iop[0]);
01101 }
01102
01108 float File::GetXCosineOnY()
01109 {
01110 float iop[6];
01111 GetImageOrientationPatient( iop );
01112 return(iop[1]);
01113 }
01114
01120 float File::GetXCosineOnZ()
01121 {
01122 float iop[6];
01123 GetImageOrientationPatient( iop );
01124 return(iop[2]);
01125 }
01126
01132 float File::GetYCosineOnX()
01133 {
01134 float iop[6];
01135 GetImageOrientationPatient( iop );
01136 return(iop[3]);
01137 }
01138
01144 float File::GetYCosineOnY()
01145 {
01146 float iop[6];
01147 GetImageOrientationPatient( iop );
01148 return(iop[4]);
01149 }
01150
01156 float File::GetYCosineOnZ()
01157 {
01158 float iop[6];
01159 GetImageOrientationPatient( iop );
01160 return(iop[5]);
01161 }
01172 bool File::GetImagePositionPatient( float ipp[3] )
01173 {
01174 std::string strImPosiPat;
01175
01176 ipp[0] = ipp[1] = ipp[2] = 0.;
01177
01178
01179 strImPosiPat = GetEntryString(0x0020,0x0032);
01180 if ( strImPosiPat != GDCM_UNFOUND )
01181 {
01182 if ( sscanf( strImPosiPat.c_str(), "%f \\ %f \\%f ",
01183 &ipp[0], &ipp[1], &ipp[2]) != 3 )
01184 {
01185 gdcmWarningMacro( "Wrong Image Position Patient (0020,0032)."
01186 << " Less than 3 values were found." );
01187 return false;
01188 }
01189 return true;
01190 }
01191
01192
01193 else if ( (strImPosiPat = GetEntryString(0x0020,0x0030)) != GDCM_UNFOUND )
01194 {
01195 if ( sscanf( strImPosiPat.c_str(), "%f \\ %f \\%f ",
01196 &ipp[0], &ipp[1], &ipp[2]) != 3 )
01197 {
01198 gdcmWarningMacro( "wrong Image Position Patient (0020,0030). "
01199 << "Less than 3 values were found." );
01200 return false;
01201 }
01202 return true;
01203 }
01204 return false;
01205 }
01206
01213 int File::GetBitsStored()
01214 {
01215 DataEntry *entry = GetDataEntry(0x0028,0x0101);
01216 if( !entry )
01217 {
01218 gdcmWarningMacro("BitsStored (0028,0101) is supposed to be mandatory");
01219 return 0;
01220 }
01221 return (int)entry->GetValue(0);
01222 }
01223
01230 int File::GetBitsAllocated()
01231 {
01232 DataEntry *entry = GetDataEntry(0x0028,0x0100);
01233 if( !entry )
01234 {
01235 gdcmWarningMacro("BitsAllocated (0028,0100) is supposed to be mandatory");
01236 return 0;
01237 }
01238 return (int)entry->GetValue(0);
01239 }
01240
01247 int File::GetHighBitPosition()
01248 {
01249 DataEntry *entry = GetDataEntry(0x0028,0x0102);
01250 if( !entry )
01251 {
01252 gdcmWarningMacro("HighBitPosition (0028,0102) is supposed to be mandatory");
01253 return 0;
01254 }
01255 return (int)entry->GetValue(0);
01256 }
01257
01264 int File::GetSamplesPerPixel()
01265 {
01266 DataEntry *entry = GetDataEntry(0x0028,0x0002);
01267 if( !entry )
01268 {
01269 gdcmWarningMacro("SamplesPerPixel (0028,0002) is supposed to be mandatory");
01270 return 1;
01271
01272 }
01273 return (int)entry->GetValue(0);
01274 }
01275
01281 int File::GetPlanarConfiguration()
01282 {
01283 DataEntry *entry = GetDataEntry(0x0028,0x0006);
01284 if( !entry )
01285 {
01286 return 0;
01287 }
01288 return (int)entry->GetValue(0);
01289 }
01290
01296 int File::GetPixelSize()
01297 {
01298
01299
01300 assert( !(GetEntryString(0x0028,0x0100) == "24") );
01301
01302 std::string pixelType = GetPixelType();
01303 if ( pixelType == "8U" || pixelType == "8S" )
01304 {
01305 return 1;
01306 }
01307 if ( pixelType == "16U" || pixelType == "16S")
01308 {
01309 return 2;
01310 }
01311 if ( pixelType == "32U" || pixelType == "32S")
01312 {
01313 return 4;
01314 }
01315 if ( pixelType == "FD" )
01316 {
01317 return 8;
01318 }
01319 gdcmWarningMacro( "Unknown pixel type: " << pixelType);
01320 return 0;
01321 }
01322
01338 std::string File::GetPixelType()
01339 {
01340 std::string bitsAlloc = GetEntryString(0x0028, 0x0100);
01341 if ( bitsAlloc == GDCM_UNFOUND )
01342 {
01343 gdcmWarningMacro( "Bits Allocated (0028,0100) supposed to be mandatory");
01344 bitsAlloc = "16";
01345 }
01346
01347 else if ( bitsAlloc == "64" )
01348 {
01349 return "FD";
01350 }
01351
01352 else if ( bitsAlloc == "12" )
01353 {
01354
01355 bitsAlloc = "16";
01356 }
01357
01358 else if ( bitsAlloc == "24" )
01359 {
01360
01361 bitsAlloc = "8";
01362 }
01363
01364 int i= atoi(bitsAlloc.c_str());
01365 if ( i > 8 && i < 16 )
01366 {
01367 bitsAlloc = "16";
01368 }
01369
01370 std::string sign;
01371 if( IsSignedPixelData() )
01372 {
01373 sign = "S";
01374 }
01375 else
01376 {
01377 sign = "U";
01378 }
01379 return bitsAlloc + sign;
01380 }
01381
01390 bool File::IsSignedPixelData()
01391 {
01392 DataEntry *entry = GetDataEntry(0x0028, 0x0103);
01393 if( !entry )
01394 {
01395 gdcmWarningMacro( "Pixel Representation (0028,0103) supposed to be "
01396 << "mandatory");
01397 return false;
01398 }
01399 return entry->GetValue(0) != 0;
01400 }
01401
01407 bool File::IsMonochrome()
01408 {
01409 const std::string &PhotometricInterp = GetEntryString( 0x0028, 0x0004 );
01410 if ( Util::DicomStringEqual(PhotometricInterp, "MONOCHROME1")
01411 || Util::DicomStringEqual(PhotometricInterp, "MONOCHROME2") )
01412 {
01413 return true;
01414 }
01415 if ( PhotometricInterp == GDCM_UNFOUND )
01416 {
01417 gdcmWarningMacro( "Photometric Interpretation (0028,0004) supposed to be "
01418 << "mandatory");
01419
01420 if (GetNumberOfScalarComponents() == 1)
01421 return true;
01422 }
01423 return false;
01424 }
01425
01431 bool File::IsMonochrome1()
01432 {
01433 const std::string &PhotometricInterp = GetEntryString( 0x0028, 0x0004 );
01434 if ( Util::DicomStringEqual(PhotometricInterp, "MONOCHROME1") )
01435 {
01436 return true;
01437 }
01438 if ( PhotometricInterp == GDCM_UNFOUND )
01439 {
01440 gdcmWarningMacro( "Photometric Interpretation (0028,0004) : supposed to"
01441 << " be mandatory! ");
01442 }
01443 return false;
01444 }
01445
01451 bool File::IsPaletteColor()
01452 {
01453 std::string PhotometricInterp = GetEntryString( 0x0028, 0x0004 );
01454 if ( PhotometricInterp == "PALETTE COLOR " )
01455 {
01456 return true;
01457 }
01458 if ( PhotometricInterp == GDCM_UNFOUND )
01459 {
01460 gdcmDebugMacro( "Not found : Palette color (0028,0004)");
01461 }
01462 return false;
01463 }
01464
01470 bool File::IsYBRFull()
01471 {
01472 std::string PhotometricInterp = GetEntryString( 0x0028, 0x0004 );
01473 if ( PhotometricInterp == "YBR_FULL" )
01474 {
01475 return true;
01476 }
01477 if ( PhotometricInterp == GDCM_UNFOUND )
01478 {
01479 gdcmDebugMacro( "Not found : YBR Full (0028,0004)");
01480 }
01481 return false;
01482 }
01483
01492 bool File::HasLUT()
01493 {
01494
01495
01496 if ( !GetDocEntry(0x0028,0x1101) )
01497 {
01498 return false;
01499 }
01500
01501 if ( !GetDocEntry(0x0028,0x1102) )
01502 {
01503 return false;
01504 }
01505
01506 if ( !GetDocEntry(0x0028,0x1103) )
01507 {
01508 return false;
01509 }
01510
01511 if ( !GetDocEntry(0x0028,0x1201) )
01512 {
01513 return false;
01514 }
01515
01516 if ( !GetDocEntry(0x0028,0x1202) )
01517 {
01518 return false;
01519 }
01520
01521 if ( !GetDocEntry(0x0028,0x1203) )
01522 {
01523 return false;
01524 }
01525
01526
01527
01528 return true;
01529 }
01530
01538 int File::GetLUTNbits()
01539 {
01540 std::vector<std::string> tokens;
01541 int lutNbits;
01542
01543
01544
01545
01546 std::string lutDescription = GetEntryString(0x0028,0x1101);
01547 if ( lutDescription == GDCM_UNFOUND )
01548 {
01549 return 0;
01550 }
01551
01552 tokens.clear();
01553 Util::Tokenize ( lutDescription, tokens, "\\" );
01554
01555
01556
01557 lutNbits = atoi( tokens[2].c_str() );
01558 tokens.clear();
01559
01560 return lutNbits;
01561 }
01562
01563
01564
01565 bool File::GetRescaleSlopeIntercept(double &slope, double &intercept)
01566 {
01567 slope = 1.0;
01568 intercept = 0.0;
01569 TS *ts = Global::GetTS();
01570 std::string sopclassuid_used;
01571
01572 const std::string &mediastoragesopclassuid_str = GetEntryString(0x0002,0x0002);
01573 const std::string &mediastoragesopclassuid = ts->GetValue(mediastoragesopclassuid_str);
01574
01575 const std::string &sopclassuid_str = GetEntryString(0x0008,0x0016);
01576 const std::string &sopclassuid = ts->GetValue(sopclassuid_str);
01577 if ( mediastoragesopclassuid == GDCM_UNFOUND && sopclassuid == GDCM_UNFOUND )
01578 {
01579 return false;
01580 }
01581 else
01582 {
01583 if( mediastoragesopclassuid == sopclassuid )
01584 {
01585 sopclassuid_used = mediastoragesopclassuid;
01586 }
01587 else
01588 {
01589 gdcmWarningMacro( "Inconsistant SOP Class UID: "
01590 << mediastoragesopclassuid << " and " << sopclassuid );
01591 return false;
01592 }
01593 }
01594
01595 if( sopclassuid_used == "Enhanced MR Image Storage" )
01596 {
01597 SeqEntry *PerframeFunctionalGroupsSequence = GetSeqEntry(0x5200,0x9230);
01598 unsigned int n = PerframeFunctionalGroupsSequence->GetNumberOfSQItems();
01599 if( !n ) return false;
01600 SQItem *item1 = PerframeFunctionalGroupsSequence->GetFirstSQItem();
01601 DocEntry *p = item1->GetDocEntry(0x0028,0x9145);
01602 if( !p ) return false;
01603 SeqEntry *seq = dynamic_cast<SeqEntry*>(p);
01604 unsigned int n1 = seq->GetNumberOfSQItems();
01605 if( !n1 ) return false;
01606 SQItem *item2 = seq->GetFirstSQItem();
01607
01608 DocEntry *p2 = item2->GetDocEntry(0x0028,0x1052);
01609 if( !p2 ) return false;
01610 DataEntry *entry = dynamic_cast<DataEntry *>(p2);
01611 std::string intercept_str = entry->GetString();
01612 if ( sscanf( intercept_str.c_str(), "%lf", &intercept) != 1 )
01613 {
01614 intercept = 0.;
01615 return false;
01616 }
01617
01618 DocEntry *p3 = item2->GetDocEntry(0x0028,0x1053);
01619 if( !p3 ) return false;
01620 DataEntry *entry2 = dynamic_cast<DataEntry *>(p3);
01621 std::string slope_str = entry2->GetString();
01622 if ( sscanf( slope_str.c_str(), "%lf", &slope) != 1 )
01623 {
01624 slope = 1.;
01625 return false;
01626 }
01627 return true;
01628 }
01629 return false;
01630 }
01631
01636 double File::GetRescaleIntercept()
01637 {
01638
01639 DataEntry *entry = GetDataEntry(0x0028, 0x1052);
01640 if( !entry )
01641 {
01642 gdcmWarningMacro( "Missing Rescale Intercept (0028,1052)");
01643 return 0.0f;
01644 }
01645 return (float)entry->GetValue(0);
01646
01647 }
01648
01653 double File::GetRescaleSlope()
01654 {
01655 double resInter = 0.;
01656 double resSlope = 1.;
01657 if ( GetRescaleSlopeIntercept(resSlope, resInter) )
01658 {
01659 return resSlope;
01660 }
01661
01662 std::string strRescSlope = GetEntryString(0x0028,0x1053);
01663 if ( strRescSlope != GDCM_UNFOUND )
01664 {
01665 if ( sscanf( strRescSlope.c_str(), "%lf ", &resSlope) != 1 )
01666 {
01667
01668 gdcmWarningMacro( "Rescale Slope (0028,1053) is empty.");
01669 }
01670 }
01671
01672 return resSlope;
01673 }
01674
01682 int File::GetNumberOfScalarComponents()
01683 {
01684 if ( GetSamplesPerPixel() == 3 )
01685 {
01686 return 3;
01687 }
01688
01689
01690
01691 if ( GetEntryString(0x0028,0x0100) == "24" )
01692 {
01693 return 3;
01694 }
01695
01696 std::string strPhotometricInterpretation = GetEntryString(0x0028,0x0004);
01697
01698 if ( ( strPhotometricInterpretation == "PALETTE COLOR ") )
01699 {
01700 if ( HasLUT() )
01701 {
01702 return 3;
01703 }
01704 else
01705 {
01706 return 1;
01707 }
01708 }
01709
01710
01711
01712 if ( strPhotometricInterpretation == GDCM_UNFOUND ||
01713 Util::DicomStringEqual(strPhotometricInterpretation, "MONOCHROME1") ||
01714 Util::DicomStringEqual(strPhotometricInterpretation, "MONOCHROME2") )
01715 {
01716 return 1;
01717 }
01718 else
01719 {
01720
01721 return 3;
01722 }
01723 }
01724
01732 int File::GetNumberOfScalarComponentsRaw()
01733 {
01734
01735
01736 if ( File::GetEntryString(0x0028,0x0100) == "24" )
01737 {
01738 return 3;
01739 }
01740
01741
01742 return GetSamplesPerPixel();
01743 }
01744
01750 size_t File::GetPixelOffset()
01751 {
01752 DocEntry *pxlElement = GetDocEntry(GrPixel, NumPixel);
01753 if ( pxlElement )
01754 {
01755 return pxlElement->GetOffset();
01756 }
01757 else
01758 {
01759 gdcmWarningMacro( "Big trouble : Pixel Element ("
01760 << std::hex << GrPixel<<","<< NumPixel<< ") NOT found" );
01761 return 0;
01762 }
01763 }
01764
01772 size_t File::GetPixelAreaLength()
01773 {
01774 DocEntry *pxlElement = GetDocEntry(GrPixel, NumPixel);
01775 if ( pxlElement )
01776 {
01777 return pxlElement->GetLength();
01778 }
01779 else
01780 {
01781 gdcmWarningMacro( "Big trouble : Pixel Element ("
01782 << std::hex << GrPixel<<","<< NumPixel<< ") NOT found" );
01783 return 0;
01784 }
01785 }
01786
01793 void File::AddAnonymizeElement (uint16_t group, uint16_t elem,
01794 std::string const &value)
01795 {
01796 DicomElement el;
01797 el.Group = group;
01798 el.Elem = elem;
01799 el.Value = value;
01800 UserAnonymizeList.push_back(el);
01801 }
01802
01807 void File::AnonymizeNoLoad()
01808 {
01809 std::fstream *fp = new std::fstream(Filename.c_str(),
01810 std::ios::in | std::ios::out | std::ios::binary);
01811 GDCM_NAME_SPACE::DocEntry *d;
01812 uint32_t offset;
01813 uint32_t lgth;
01814 uint32_t valLgth = 0;
01815 std::string *spaces;
01816 for (ListElements::iterator it = UserAnonymizeList.begin();
01817 it != UserAnonymizeList.end();
01818 ++it)
01819 {
01820
01821
01822
01823
01824 d = GetDocEntry( (*it).Group, (*it).Elem);
01825
01826 if ( d == NULL)
01827 continue;
01828
01829 if ( dynamic_cast<SeqEntry *>(d) )
01830 {
01831 gdcmWarningMacro( "You cannot 'Anonymize' a SeqEntry ");
01832 continue;
01833 }
01834
01835 valLgth = (*it).Value.size();
01836 if (valLgth == 0)
01837 continue;
01838
01839 offset = d->GetOffset();
01840 lgth = d->GetLength();
01841
01842
01843 if (valLgth < lgth)
01844 {
01845 spaces = new std::string( lgth-valLgth, ' ');
01846 (*it).Value = (*it).Value + *spaces;
01847
01848 delete spaces;
01849 }
01850 fp->seekp( offset, std::ios::beg );
01851 fp->write( (*it).Value.c_str(), lgth );
01852
01853 }
01854 fp->close();
01855 delete fp;
01856 }
01857
01863 bool File::AnonymizeFile()
01864 {
01865
01866 if ( UserAnonymizeList.begin() == UserAnonymizeList.end() )
01867 {
01868
01869 SetEntryString(" ",0x0010, 0x2154);
01870 SetEntryString(" ",0x0010, 0x1040);
01871 SetEntryString(" ",0x0010, 0x0020);
01872
01873 DocEntry *patientNameHE = GetDocEntry (0x0010, 0x0010);
01874
01875 if ( patientNameHE )
01876 {
01877 std::string studyInstanceUID = GetEntryString (0x0020, 0x000d);
01878 if ( studyInstanceUID != GDCM_UNFOUND )
01879 {
01880 SetEntryString(studyInstanceUID, 0x0010, 0x0010);
01881 }
01882 else
01883 {
01884 SetEntryString("anonymized", 0x0010, 0x0010);
01885 }
01886 }
01887 }
01888 else
01889 {
01890 GDCM_NAME_SPACE::DocEntry *d;
01891 for (ListElements::iterator it = UserAnonymizeList.begin();
01892 it != UserAnonymizeList.end();
01893 ++it)
01894 {
01895 d = GetDocEntry( (*it).Group, (*it).Elem);
01896
01897 if ( d == NULL)
01898 continue;
01899
01900 if ( dynamic_cast<SeqEntry *>(d) )
01901 {
01902 gdcmWarningMacro( "You cannot 'Anonymize' a SeqEntry ");
01903 continue;
01904 }
01905
01906 if ( dynamic_cast<DataEntry *>(d) )
01907 {
01908 gdcmWarningMacro( "To 'Anonymize' a DataEntry, better use AnonymizeNoLoad (FIXME) ");
01909 continue;
01910 }
01911 else
01912 SetEntryString ((*it).Value, (*it).Group, (*it).Elem);
01913 }
01914 }
01915
01916
01917
01918
01919
01920
01921
01922
01923
01924
01925
01926
01927
01928
01929
01930
01931
01932
01933
01934
01935
01936
01937
01938
01939
01940
01941
01942
01943
01944
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961
01962
01963
01964
01965
01966
01967
01968 return true;
01969 }
01970
01979 bool File::Write(std::string fileName, FileType writetype)
01980 {
01981 gdcmDebugMacro(" File::Write ");
01982 std::ofstream *fp = new std::ofstream(fileName.c_str(),
01983 std::ios::out | std::ios::binary);
01984 if (*fp == NULL)
01985 {
01986 gdcmWarningMacro("Failed to open (write) File: " << fileName.c_str());
01987 return false;
01988 }
01989
01990
01991 DataEntry *e0000 = GetDataEntry(0x0002,0x0000);
01992 if ( e0000 )
01993 {
01994 std::ostringstream sLen;
01995 sLen << ComputeGroup0002Length( );
01996 e0000->SetString(sLen.str());
01997 }
01998
02000 if( writetype != JPEG )
02001 {
02002 int i_lgPix = GetEntryLength(GrPixel, NumPixel);
02003 if (i_lgPix != -2)
02004 {
02005
02006 std::string s_lgPix = Util::Format("%d", i_lgPix+12);
02007 s_lgPix = Util::DicomString( s_lgPix.c_str() );
02008 InsertEntryString(s_lgPix,GrPixel, 0x0000, "UL");
02009 }
02010 }
02011 Document::WriteContent(fp, writetype);
02012
02013 fp->close();
02014 delete fp;
02015
02016 return true;
02017 }
02018
02019
02020
02021
02022
02023
02024
02030 void File::ComputeRLEInfo()
02031 {
02032 std::string ts = GetTransferSyntax();
02033 if ( !Global::GetTS()->IsRLELossless(ts) )
02034 {
02035 return;
02036 }
02037
02038
02039
02040
02041
02042
02043
02044
02045
02046
02047
02048
02049
02050
02051 ReadEncapsulatedBasicOffsetTable();
02052
02053
02054
02055
02056
02057
02058
02059
02060 long frameLength;
02061 int i=0;
02062 uint32_t sum = 0;
02063 while ( (frameLength = ReadTagLength(0xfffe, 0xe000)) != 0 )
02064 {
02065
02066
02067 if ( BasicOffsetTableItemValue )
02068 {
02069
02070 uint32_t individualLength = BasicOffsetTableItemValue[i];
02071 assert( individualLength == sum );
02072 if( individualLength != sum )
02073 {
02074 gdcmWarningMacro( "BasicOffsetTableItemValue differs from the fragment lenght" );
02075 }
02076 sum += frameLength + 8;
02077 i++;
02078 }
02079
02080
02081
02082
02083 long frameOffset = Fp->tellg();
02084
02085 uint32_t nbRleSegments = ReadInt32();
02086 if ( nbRleSegments > 16 )
02087 {
02088
02089 gdcmWarningMacro( "Too many segments.");
02090 }
02091
02092 uint32_t rleSegmentOffsetTable[16];
02093 for( int k = 1; k <= 15; k++ )
02094 {
02095 rleSegmentOffsetTable[k] = ReadInt32();
02096 }
02097
02098
02099
02100
02101 long rleSegmentLength[15];
02102
02103 if ( nbRleSegments > 1)
02104 {
02105 for(unsigned int k = 1; k <= nbRleSegments-1; k++)
02106 {
02107 rleSegmentLength[k] = rleSegmentOffsetTable[k+1]
02108 - rleSegmentOffsetTable[k];
02109 SkipBytes(rleSegmentLength[k]);
02110 }
02111 }
02112
02113 rleSegmentLength[nbRleSegments] = frameLength
02114 - rleSegmentOffsetTable[nbRleSegments];
02115 SkipBytes(rleSegmentLength[nbRleSegments]);
02116
02117
02118 RLEFrame *newFrame = new RLEFrame;
02119 newFrame->SetNumberOfFragments(nbRleSegments);
02120 for( unsigned int uk = 1; uk <= nbRleSegments; uk++ )
02121 {
02122 newFrame->SetOffset(uk,frameOffset + rleSegmentOffsetTable[uk]);
02123 newFrame->SetLength(uk,rleSegmentLength[uk]);
02124 }
02125 RLEInfo->AddFrame(newFrame);
02126 }
02127
02128
02129
02130 if ( !ReadTag(0xfffe, 0xe0dd) )
02131 {
02132 gdcmWarningMacro( "No sequence delimiter item at end of RLE item sequence");
02133 }
02134 }
02135
02142 void File::ComputeJPEGFragmentInfo()
02143 {
02144
02145 std::string ts = GetTransferSyntax();
02146 if ( ! Global::GetTS()->IsJPEG(ts) )
02147 {
02148 return;
02149 }
02150
02151 ReadEncapsulatedBasicOffsetTable();
02152
02153
02154
02155 long fragmentLength;
02156 int i=0;
02157 uint32_t sum = 0;
02158 while ( (fragmentLength = ReadTagLength(0xfffe, 0xe000)) != 0 )
02159 {
02160
02161
02162
02163
02164
02165
02166
02167
02168
02169 if ( BasicOffsetTableItemValue )
02170 {
02171
02172 uint32_t individualLength = BasicOffsetTableItemValue[i];
02173
02174 if( individualLength != sum )
02175 {
02176 gdcmWarningMacro( "BasicOffsetTableItemValue differs from the fragment lenght:" <<
02177 individualLength << " != " << sum );
02178 }
02179 sum += fragmentLength + 8;
02180 i++;
02181 }
02182
02183 long fragmentOffset = Fp->tellg();
02184
02185 JPEGFragment *newFragment = new JPEGFragment;
02186 newFragment->SetOffset(fragmentOffset);
02187 newFragment->SetLength(fragmentLength);
02188 JPEGInfo->AddFragment(newFragment);
02189
02190 SkipBytes(fragmentLength);
02191 }
02192
02193
02194
02195 if ( !ReadTag(0xfffe, 0xe0dd) )
02196 {
02197 gdcmWarningMacro( "No sequence delimiter item at end of JPEG item sequence");
02198 }
02199 }
02200
02214 bool File::ReadTag(uint16_t testGroup, uint16_t testElem)
02215 {
02216 long positionOnEntry = Fp->tellg();
02217
02218
02219
02220
02221 uint16_t itemTagGroup;
02222 uint16_t itemTagElem;
02223 try
02224 {
02225 itemTagGroup = ReadInt16();
02226 itemTagElem = ReadInt16();
02227 }
02228 catch ( FormatError )
02229 {
02230 gdcmErrorMacro( "Can not read tag for "
02231 << " We should have found tag ("
02232 << DictEntry::TranslateToKey(testGroup,testElem) << ")"
02233 ) ;
02234
02235 return false;
02236 }
02237 if ( itemTagGroup != testGroup || itemTagElem != testElem )
02238 {
02239
02240 if (itemTagGroup != 0xfffe || testGroup != 0xfffe )
02241 gdcmWarningMacro( "Wrong Item Tag found:"
02242 << " We should have found tag ("
02243 << DictEntry::TranslateToKey(testGroup,testElem) << ")" << std::endl
02244 << " but instead we encountered tag ("
02245 << DictEntry::TranslateToKey(itemTagGroup,itemTagElem) << ")"
02246 << " at address: " << " 0x(" << std::hex
02247 << (unsigned int)positionOnEntry << std::dec << ")"
02248 ) ;
02249 Fp->seekg(positionOnEntry, std::ios::beg);
02250
02251 return false;
02252 }
02253 return true;
02254 }
02255
02270 uint32_t File::ReadTagLength(uint16_t testGroup, uint16_t testElem)
02271 {
02272
02273 if ( !ReadTag(testGroup, testElem) )
02274 {
02275
02276 if ( testGroup != 0xfffe )
02277 gdcmErrorMacro( "ReadTag did not succeed for ("
02278 << DictEntry::TranslateToKey(testGroup,testElem)
02279 << ")..." );
02280 return 0;
02281 }
02282
02284
02285
02286 uint32_t itemLength = ReadInt32();
02287 gdcmDebugMacro( "Basic Item Length is: " << itemLength
02288
02289 );
02290 return itemLength;
02291 }
02292
02297 void File::ReadEncapsulatedBasicOffsetTable()
02298 {
02300 uint32_t itemLength = ReadTagLength(0xfffe, 0xe000);
02301
02302
02303
02304
02305
02306
02307
02308 if ( itemLength != 0 )
02309 {
02310 char *charBasicOffsetTableItemValue = new char[itemLength];
02311 Fp->read(charBasicOffsetTableItemValue, itemLength);
02312 unsigned int nbEntries = itemLength/4;
02313 assert( nbEntries*4 == itemLength);
02314 BasicOffsetTableItemValue = new uint32_t[nbEntries];
02315
02316 for (unsigned int i=0; i < nbEntries; i++ )
02317 {
02318 BasicOffsetTableItemValue[i] = *((uint32_t*)(&charBasicOffsetTableItemValue[4*i]));
02319 #if defined(GDCM_WORDS_BIGENDIAN) || defined(GDCM_FORCE_BIGENDIAN_EMULATION)
02320 uint32_t val = BasicOffsetTableItemValue[i];
02321 BasicOffsetTableItemValue[i]
02322 = ( (val<<24) | ((val<<8) & 0x00ff0000) |
02323 ( (val>>8) & 0x0000ff00) | (val>>24) );
02324 #endif
02325 gdcmDebugMacro( "Read one length for: " <<
02326 std::hex << BasicOffsetTableItemValue[i] );
02327 }
02328
02329 delete[] charBasicOffsetTableItemValue;
02330 }
02331 }
02332
02333
02334
02335
02336
02337
02338
02339
02340
02341
02342
02343
02344
02345
02346
02347
02348
02349
02350
02351
02352
02353
02354
02355
02356
02357
02358
02359
02360 }