00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "gdcmFileHelper.h"
00021 #include "gdcmGlobal.h"
00022 #include "gdcmTS.h"
00023 #include "gdcmDocument.h"
00024 #include "gdcmDebug.h"
00025 #include "gdcmUtil.h"
00026 #include "gdcmSeqEntry.h"
00027 #include "gdcmSQItem.h"
00028 #include "gdcmDataEntry.h"
00029 #include "gdcmFile.h"
00030 #include "gdcmPixelReadConvert.h"
00031 #include "gdcmPixelWriteConvert.h"
00032 #include "gdcmDocEntryArchive.h"
00033 #include "gdcmDictSet.h"
00034 #include "gdcmOrientation.h"
00035
00036 #include <fstream>
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
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115 namespace gdcm
00116 {
00117 typedef std::map<uint16_t, int> GroupHT;
00118
00119
00133 FileHelper::FileHelper( )
00134 {
00135 FileInternal = File::New( );
00136 Initialize();
00137 }
00138
00153 FileHelper::FileHelper(File *header)
00154 {
00155 gdcmAssertMacro(header);
00156
00157 FileInternal = header;
00158 FileInternal->Register();
00159 Initialize();
00160 if ( FileInternal->IsReadable() )
00161 {
00162 PixelReadConverter->GrabInformationsFromFile( FileInternal, this );
00163 }
00164 }
00165
00171 FileHelper::~FileHelper()
00172 {
00173 if ( PixelReadConverter )
00174 {
00175 delete PixelReadConverter;
00176 }
00177 if ( PixelWriteConverter )
00178 {
00179 delete PixelWriteConverter;
00180 }
00181 if ( Archive )
00182 {
00183 delete Archive;
00184 }
00185
00186 FileInternal->Unregister();
00187 }
00188
00189
00190
00191
00200 void FileHelper::SetLoadMode(int loadMode)
00201 {
00202 GetFile()->SetLoadMode( loadMode );
00203 }
00208 void FileHelper::SetFileName(std::string const &fileName)
00209 {
00210 FileInternal->SetFileName( fileName );
00211 }
00212
00218 bool FileHelper::Load()
00219 {
00220 if ( !FileInternal->Load() )
00221 return false;
00222
00223 PixelReadConverter->GrabInformationsFromFile( FileInternal, this );
00224 return true;
00225 }
00226
00235 bool FileHelper::SetEntryString(std::string const &content,
00236 uint16_t group, uint16_t elem)
00237 {
00238 return FileInternal->SetEntryString(content, group, elem);
00239 }
00240
00241
00251 bool FileHelper::SetEntryBinArea(uint8_t *content, int lgth,
00252 uint16_t group, uint16_t elem)
00253 {
00254 return FileInternal->SetEntryBinArea(content, lgth, group, elem);
00255 }
00256
00266 DataEntry *FileHelper::InsertEntryString(std::string const &content,
00267 uint16_t group, uint16_t elem)
00268 {
00269 return FileInternal->InsertEntryString(content, group, elem);
00270 }
00271
00283 DataEntry *FileHelper::InsertEntryBinArea(uint8_t *binArea, int lgth,
00284 uint16_t group, uint16_t elem)
00285 {
00286 return FileInternal->InsertEntryBinArea(binArea, lgth, group, elem);
00287 }
00288
00297 SeqEntry *FileHelper::InsertSeqEntry(uint16_t group, uint16_t elem)
00298 {
00299 return FileInternal->InsertSeqEntry(group, elem);
00300 }
00301
00310 size_t FileHelper::GetImageDataSize()
00311 {
00312 if ( PixelWriteConverter->GetUserData() )
00313 {
00314 return PixelWriteConverter->GetUserDataSize();
00315 }
00316 return PixelReadConverter->GetRGBSize();
00317 }
00318
00326 size_t FileHelper::GetImageDataRawSize()
00327 {
00328 if ( PixelWriteConverter->GetUserData() )
00329 {
00330 return PixelWriteConverter->GetUserDataSize();
00331 }
00332 return PixelReadConverter->GetRawSize();
00333 }
00334
00347 uint8_t *FileHelper::GetImageData()
00348 {
00349 if ( PixelWriteConverter->GetUserData() )
00350 {
00351 return PixelWriteConverter->GetUserData();
00352 }
00353
00354 if ( ! GetRaw() )
00355 {
00356
00357 return 0;
00358 }
00359
00360 if ( FileInternal->HasLUT() && PixelReadConverter->BuildRGBImage() )
00361 {
00362 return PixelReadConverter->GetRGB();
00363 }
00364 else
00365 {
00366
00367 return PixelReadConverter->GetRaw();
00368 }
00369 }
00370
00382 uint8_t *FileHelper::GetImageDataRaw ()
00383 {
00384 return GetRaw();
00385 }
00386
00387 #ifndef GDCM_LEGACY_REMOVE
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414 size_t FileHelper::GetImageDataIntoVector (void *destination, size_t maxSize)
00415 {
00416 if ( ! GetRaw() )
00417 {
00418
00419 return 0;
00420 }
00421
00422 if ( FileInternal->HasLUT() && PixelReadConverter->BuildRGBImage() )
00423 {
00424 if ( PixelReadConverter->GetRGBSize() > maxSize )
00425 {
00426 gdcmWarningMacro( "Pixel data bigger than caller's expected MaxSize");
00427 return 0;
00428 }
00429 memcpy( destination,
00430 (void*)PixelReadConverter->GetRGB(),
00431 PixelReadConverter->GetRGBSize() );
00432 return PixelReadConverter->GetRGBSize();
00433 }
00434
00435
00436 if ( PixelReadConverter->GetRawSize() > maxSize )
00437 {
00438 gdcmWarningMacro( "Pixel data bigger than caller's expected MaxSize");
00439 return 0;
00440 }
00441 memcpy( destination,
00442 (void *)PixelReadConverter->GetRaw(),
00443 PixelReadConverter->GetRawSize() );
00444 return PixelReadConverter->GetRawSize();
00445 }
00446 #endif
00447
00461 void FileHelper::SetImageData(uint8_t *inData, size_t expectedSize)
00462 {
00463 SetUserData(inData, expectedSize);
00464 }
00465
00474 void FileHelper::SetUserData(uint8_t *inData, size_t expectedSize)
00475 {
00476 PixelWriteConverter->SetUserData(inData, expectedSize);
00477 }
00478
00483 uint8_t *FileHelper::GetUserData()
00484 {
00485 return PixelWriteConverter->GetUserData();
00486 }
00487
00492 size_t FileHelper::GetUserDataSize()
00493 {
00494 return PixelWriteConverter->GetUserDataSize();
00495 }
00496
00501 uint8_t *FileHelper::GetRGBData()
00502 {
00503 return PixelReadConverter->GetRGB();
00504 }
00505
00510 size_t FileHelper::GetRGBDataSize()
00511 {
00512 return PixelReadConverter->GetRGBSize();
00513 }
00514
00519 uint8_t *FileHelper::GetRawData()
00520 {
00521 return PixelReadConverter->GetRaw();
00522 }
00523
00528 size_t FileHelper::GetRawDataSize()
00529 {
00530 return PixelReadConverter->GetRawSize();
00531 }
00532
00536 uint8_t* FileHelper::GetLutRGBA()
00537 {
00538 if ( PixelReadConverter->GetLutRGBA() ==0 )
00539 PixelReadConverter->BuildLUTRGBA();
00540 return PixelReadConverter->GetLutRGBA();
00541 }
00542
00546 int FileHelper::GetLutItemNumber()
00547 {
00548 return PixelReadConverter->GetLutItemNumber();
00549 }
00550
00554 int FileHelper::GetLutItemSize()
00555 {
00556 return PixelReadConverter->GetLutItemSize();
00557 }
00558
00567 bool FileHelper::WriteRawData(std::string const &fileName)
00568 {
00569 std::ofstream fp1(fileName.c_str(), std::ios::out | std::ios::binary );
00570 if (!fp1)
00571 {
00572 gdcmWarningMacro( "Fail to open (write) file:" << fileName.c_str());
00573 return false;
00574 }
00575
00576 if ( PixelWriteConverter->GetUserData() )
00577 {
00578 fp1.write( (char *)PixelWriteConverter->GetUserData(),
00579 PixelWriteConverter->GetUserDataSize() );
00580 }
00581 else if ( PixelReadConverter->GetRGB() )
00582 {
00583 fp1.write( (char *)PixelReadConverter->GetRGB(),
00584 PixelReadConverter->GetRGBSize());
00585 }
00586 else if ( PixelReadConverter->GetRaw() )
00587 {
00588 fp1.write( (char *)PixelReadConverter->GetRaw(),
00589 PixelReadConverter->GetRawSize());
00590 }
00591 else
00592 {
00593 gdcmErrorMacro( "Nothing written." );
00594 }
00595
00596 fp1.close();
00597
00598 return true;
00599 }
00600
00610 bool FileHelper::WriteDcmImplVR (std::string const &fileName)
00611 {
00612 SetWriteTypeToDcmImplVR();
00613 return Write(fileName);
00614 }
00615
00625 bool FileHelper::WriteDcmExplVR (std::string const &fileName)
00626 {
00627 SetWriteTypeToDcmExplVR();
00628 return Write(fileName);
00629 }
00630
00645 bool FileHelper::WriteAcr (std::string const &fileName)
00646 {
00647 SetWriteTypeToAcr();
00648 return Write(fileName);
00649 }
00650
00657 bool FileHelper::Write(std::string const &fileName)
00658 {
00659 switch(WriteType)
00660 {
00661 case ImplicitVR:
00662 SetWriteFileTypeToImplicitVR();
00663 break;
00664 case Unknown:
00665 case ExplicitVR:
00666 SetWriteFileTypeToExplicitVR();
00667 break;
00668 case ACR:
00669 case ACR_LIBIDO:
00670
00671
00672
00673
00674
00675
00676 if ( ! FileInternal->GetDataEntry(0x0008, 0x0010) )
00677 FileInternal->InsertEntryString("ACR-NEMA V1.0 ", 0x0008, 0x0010);
00678 SetWriteFileTypeToACR();
00679
00680 break;
00681 case JPEG:
00682 SetWriteFileTypeToJPEG();
00683 std::cerr << "Writting as JPEG" << std::endl;
00684 break;
00685 }
00686 CheckMandatoryElements();
00687
00688
00689
00690
00691
00692
00693
00696
00697 if ( WriteType == ACR_LIBIDO )
00698 {
00699 SetWriteToLibido();
00700 }
00701 else
00702 {
00703 SetWriteToNoLibido();
00704 }
00705
00706
00707 switch(WriteMode)
00708 {
00709 case WMODE_RAW :
00710 SetWriteToRaw();
00711 break;
00712 case WMODE_RGB :
00713 SetWriteToRGB();
00714 break;
00715 }
00716
00717 bool check = CheckWriteIntegrity();
00718 if (WriteType == JPEG ) check = true;
00719 if (check)
00720 {
00721 check = FileInternal->Write(fileName,WriteType);
00722 }
00723
00724 RestoreWrite();
00725 RestoreWriteFileType();
00726 RestoreWriteMandatory();
00727
00728
00729
00730
00731
00732
00733 RestoreWriteOfLibido();
00734
00735
00736 return check;
00737 }
00738
00739
00740
00749 bool FileHelper::CheckWriteIntegrity()
00750 {
00751 if ( PixelWriteConverter->GetUserData() )
00752 {
00753 int numberBitsAllocated = FileInternal->GetBitsAllocated();
00754 if ( numberBitsAllocated == 0 || numberBitsAllocated == 12 )
00755 {
00756 gdcmWarningMacro( "numberBitsAllocated changed from "
00757 << numberBitsAllocated << " to 16 "
00758 << " for consistency purpose" );
00759 numberBitsAllocated = 16;
00760 }
00761
00762 size_t decSize = FileInternal->GetXSize()
00763 * FileInternal->GetYSize()
00764 * FileInternal->GetZSize()
00765 * FileInternal->GetSamplesPerPixel()
00766 * ( numberBitsAllocated / 8 );
00767 size_t rgbSize = decSize;
00768 if ( FileInternal->HasLUT() )
00769 rgbSize = decSize * 3;
00770
00771 switch(WriteMode)
00772 {
00773 case WMODE_RAW :
00774 if ( decSize!=PixelWriteConverter->GetUserDataSize() )
00775 {
00776 gdcmWarningMacro( "Data size (Raw) is incorrect. Should be "
00777 << decSize << " / Found :"
00778 << PixelWriteConverter->GetUserDataSize() );
00779 return false;
00780 }
00781 break;
00782 case WMODE_RGB :
00783 if ( rgbSize!=PixelWriteConverter->GetUserDataSize() )
00784 {
00785 gdcmWarningMacro( "Data size (RGB) is incorrect. Should be "
00786 << decSize << " / Found "
00787 << PixelWriteConverter->GetUserDataSize() );
00788 return false;
00789 }
00790 break;
00791 }
00792 }
00793
00794 return true;
00795 }
00796
00802 void FileHelper::SetWriteToRaw()
00803 {
00804 if ( FileInternal->GetNumberOfScalarComponents() == 3
00805 && !FileInternal->HasLUT() )
00806 {
00807 SetWriteToRGB();
00808 }
00809 else
00810 {
00811 DataEntry *photInt = CopyDataEntry(0x0028,0x0004);
00812 if (FileInternal->HasLUT() )
00813 {
00814 photInt->SetString("PALETTE COLOR ");
00815 }
00816 else
00817 {
00818 photInt->SetString("MONOCHROME2 ");
00819 }
00820
00821 PixelWriteConverter->SetReadData(PixelReadConverter->GetRaw(),
00822 PixelReadConverter->GetRawSize());
00823
00824 std::string vr = "OB";
00825 if ( FileInternal->GetBitsAllocated()>8 )
00826 vr = "OW";
00827 if ( FileInternal->GetBitsAllocated()==24 )
00828 vr = "OB";
00829 DataEntry *pixel =
00830 CopyDataEntry(GetFile()->GetGrPixel(),GetFile()->GetNumPixel(),vr);
00831 pixel->SetFlag(DataEntry::FLAG_PIXELDATA);
00832 pixel->SetBinArea(PixelWriteConverter->GetData(),false);
00833 pixel->SetLength(PixelWriteConverter->GetDataSize());
00834
00835 Archive->Push(photInt);
00836 Archive->Push(pixel);
00837
00838 photInt->Delete();
00839 pixel->Delete();
00840 }
00841 }
00842
00850 void FileHelper::SetWriteToRGB()
00851 {
00852 if ( FileInternal->GetNumberOfScalarComponents()==3 )
00853 {
00854 PixelReadConverter->BuildRGBImage();
00855
00856 DataEntry *spp = CopyDataEntry(0x0028,0x0002);
00857 spp->SetString("3 ");
00858
00859 DataEntry *planConfig = CopyDataEntry(0x0028,0x0006);
00860 planConfig->SetString("0 ");
00861
00862 DataEntry *photInt = CopyDataEntry(0x0028,0x0004);
00863 photInt->SetString("RGB ");
00864
00865 if ( PixelReadConverter->GetRGB() )
00866 {
00867 PixelWriteConverter->SetReadData(PixelReadConverter->GetRGB(),
00868 PixelReadConverter->GetRGBSize());
00869 }
00870 else
00871 {
00872 PixelWriteConverter->SetReadData(PixelReadConverter->GetRaw(),
00873 PixelReadConverter->GetRawSize());
00874 }
00875
00876 std::string vr = "OB";
00877 if ( FileInternal->GetBitsAllocated()>8 )
00878 vr = "OW";
00879 if ( FileInternal->GetBitsAllocated()==24 )
00880 vr = "OB";
00881 DataEntry *pixel =
00882 CopyDataEntry(GetFile()->GetGrPixel(),GetFile()->GetNumPixel(),vr);
00883 pixel->SetFlag(DataEntry::FLAG_PIXELDATA);
00884 pixel->SetBinArea(PixelWriteConverter->GetData(),false);
00885 pixel->SetLength(PixelWriteConverter->GetDataSize());
00886
00887 Archive->Push(spp);
00888 Archive->Push(planConfig);
00889 Archive->Push(photInt);
00890 Archive->Push(pixel);
00891
00892 spp->Delete();
00893 planConfig->Delete();
00894 photInt->Delete();
00895 pixel->Delete();
00896
00897
00898 Archive->Push(0x0028,0x1101);
00899 Archive->Push(0x0028,0x1102);
00900 Archive->Push(0x0028,0x1103);
00901 Archive->Push(0x0028,0x1201);
00902 Archive->Push(0x0028,0x1202);
00903 Archive->Push(0x0028,0x1203);
00904
00905
00906 Archive->Push(0x0028,0x1199);
00907
00908
00909
00910
00911 if ( FileInternal->GetBitsAllocated()==24 )
00912 {
00913 DataEntry *bitsAlloc = CopyDataEntry(0x0028,0x0100);
00914 bitsAlloc->SetString("8 ");
00915
00916 DataEntry *bitsStored = CopyDataEntry(0x0028,0x0101);
00917 bitsStored->SetString("8 ");
00918
00919 DataEntry *highBit = CopyDataEntry(0x0028,0x0102);
00920 highBit->SetString("7 ");
00921
00922 Archive->Push(bitsAlloc);
00923 Archive->Push(bitsStored);
00924 Archive->Push(highBit);
00925
00926 bitsAlloc->Delete();
00927 bitsStored->Delete();
00928 highBit->Delete();
00929 }
00930 }
00931 else
00932 {
00933 SetWriteToRaw();
00934 }
00935 }
00936
00940 void FileHelper::RestoreWrite()
00941 {
00942 Archive->Restore(0x0028,0x0002);
00943 Archive->Restore(0x0028,0x0004);
00944 Archive->Restore(0x0028,0x0006);
00945 Archive->Restore(GetFile()->GetGrPixel(),GetFile()->GetNumPixel());
00946
00947
00948 Archive->Restore(0x0028,0x0100);
00949 Archive->Restore(0x0028,0x0101);
00950 Archive->Restore(0x0028,0x0102);
00951
00952
00953 Archive->Restore(0x0028,0x1101);
00954 Archive->Restore(0x0028,0x1102);
00955 Archive->Restore(0x0028,0x1103);
00956 Archive->Restore(0x0028,0x1201);
00957 Archive->Restore(0x0028,0x1202);
00958 Archive->Restore(0x0028,0x1203);
00959
00960
00961 Archive->Restore(0x0028,0x1203);
00962
00963
00964
00965 Archive->Restore(0x0002,0x0000);
00966 Archive->Restore(0x0002,0x0001);
00967 Archive->Restore(0x0002,0x0002);
00968 Archive->Restore(0x0002,0x0003);
00969 Archive->Restore(0x0002,0x0010);
00970 Archive->Restore(0x0002,0x0012);
00971 Archive->Restore(0x0002,0x0013);
00972 Archive->Restore(0x0002,0x0016);
00973 Archive->Restore(0x0002,0x0100);
00974 Archive->Restore(0x0002,0x0102);
00975 }
00976
00984 void FileHelper::SetWriteFileTypeToACR()
00985 {
00986 Archive->Push(0x0002,0x0000);
00987 Archive->Push(0x0002,0x0001);
00988 Archive->Push(0x0002,0x0002);
00989 Archive->Push(0x0002,0x0003);
00990 Archive->Push(0x0002,0x0010);
00991 Archive->Push(0x0002,0x0012);
00992 Archive->Push(0x0002,0x0013);
00993 Archive->Push(0x0002,0x0016);
00994 Archive->Push(0x0002,0x0100);
00995 Archive->Push(0x0002,0x0102);
00996 }
00997
01001 void FileHelper::SetWriteFileTypeToJPEG()
01002 {
01003 std::string ts = Util::DicomString(
01004 Global::GetTS()->GetSpecialTransferSyntax(TS::JPEGBaselineProcess1) );
01005
01006 DataEntry *tss = CopyDataEntry(0x0002,0x0010);
01007 tss->SetString(ts);
01008
01009 Archive->Push(tss);
01010 tss->Delete();
01011 }
01012
01013 void FileHelper::SetWriteFileTypeToExplicitVR()
01014 {
01015 std::string ts = Util::DicomString(
01016 Global::GetTS()->GetSpecialTransferSyntax(TS::ExplicitVRLittleEndian) );
01017
01018 DataEntry *tss = CopyDataEntry(0x0002,0x0010);
01019 tss->SetString(ts);
01020
01021 Archive->Push(tss);
01022 tss->Delete();
01023 }
01024
01028 void FileHelper::SetWriteFileTypeToImplicitVR()
01029 {
01030 std::string ts = Util::DicomString(
01031 Global::GetTS()->GetSpecialTransferSyntax(TS::ImplicitVRLittleEndian) );
01032
01033 DataEntry *tss = CopyDataEntry(0x0002,0x0010);
01034 tss->SetString(ts);
01035
01036 Archive->Push(tss);
01037 tss->Delete();
01038 }
01039
01040
01044 void FileHelper::RestoreWriteFileType()
01045 {
01046 }
01047
01051 void FileHelper::SetWriteToLibido()
01052 {
01053 DataEntry *oldRow = FileInternal->GetDataEntry(0x0028, 0x0010);
01054 DataEntry *oldCol = FileInternal->GetDataEntry(0x0028, 0x0011);
01055
01056 if ( oldRow && oldCol )
01057 {
01058 std::string rows, columns;
01059
01060 DataEntry *newRow=DataEntry::New(oldRow->GetDictEntry());
01061 DataEntry *newCol=DataEntry::New(oldCol->GetDictEntry());
01062
01063 newRow->Copy(oldCol);
01064 newCol->Copy(oldRow);
01065
01066 newRow->SetString(oldCol->GetString());
01067 newCol->SetString(oldRow->GetString());
01068
01069 Archive->Push(newRow);
01070 Archive->Push(newCol);
01071
01072 newRow->Delete();
01073 newCol->Delete();
01074 }
01075
01076 DataEntry *libidoCode = CopyDataEntry(0x0008,0x0010);
01077 libidoCode->SetString("ACRNEMA_LIBIDO_1.1");
01078 Archive->Push(libidoCode);
01079 libidoCode->Delete();
01080 }
01081
01085 void FileHelper::SetWriteToNoLibido()
01086 {
01087 DataEntry *recCode = FileInternal->GetDataEntry(0x0008,0x0010);
01088 if ( recCode )
01089 {
01090 if ( recCode->GetString() == "ACRNEMA_LIBIDO_1.1" )
01091 {
01092 DataEntry *libidoCode = CopyDataEntry(0x0008,0x0010);
01093 libidoCode->SetString("");
01094 Archive->Push(libidoCode);
01095 libidoCode->Delete();
01096 }
01097 }
01098 }
01099
01103 void FileHelper::RestoreWriteOfLibido()
01104 {
01105 Archive->Restore(0x0028,0x0010);
01106 Archive->Restore(0x0028,0x0011);
01107 Archive->Restore(0x0008,0x0010);
01108
01109
01110 Archive->Restore(0x0028,0x0015);
01111 Archive->Restore(0x0028,0x0016);
01112 Archive->Restore(0x0028,0x0017);
01113 Archive->Restore(0x0028,0x00199);
01114 }
01115
01124 DataEntry *FileHelper::CopyDataEntry(uint16_t group, uint16_t elem,
01125 const TagName &vr)
01126 {
01127 DocEntry *oldE = FileInternal->GetDocEntry(group, elem);
01128 DataEntry *newE;
01129
01130 if ( oldE && vr != GDCM_VRUNKNOWN )
01131 if ( oldE->GetVR() != vr )
01132 oldE = NULL;
01133
01134 if ( oldE )
01135 {
01136 newE = DataEntry::New(oldE->GetDictEntry());
01137 newE->Copy(oldE);
01138 }
01139 else
01140 {
01141 newE = GetFile()->NewDataEntry(group, elem, vr);
01142 }
01143
01144 return newE;
01145 }
01146
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
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
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327 void FileHelper::CheckMandatoryElements()
01328 {
01329 std::string sop = Util::CreateUniqueUID();
01330
01331
01332 if ( WriteType != ACR && WriteType != ACR_LIBIDO )
01333 {
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350 CopyMandatoryEntry(0x0002,0x0000,"0");
01351
01352 DataEntry *e_0002_0001 = CopyDataEntry(0x0002,0x0001, "OB");
01353 e_0002_0001->SetBinArea((uint8_t*)Util::GetFileMetaInformationVersion(),
01354 false);
01355 e_0002_0001->SetLength(2);
01356 Archive->Push(e_0002_0001);
01357 e_0002_0001->Delete();
01358
01359 if ( KeepMediaStorageSOPClassUID)
01360
01361
01362 CheckMandatoryEntry(0x0002,0x0002,"1.2.840.10008.5.1.4.1.1.7");
01363 else
01364
01365
01366 CopyMandatoryEntry(0x0002,0x0002,"1.2.840.10008.5.1.4.1.1.7");
01367
01368
01369 CopyMandatoryEntry(0x0002,0x0003,sop);
01370
01371
01372
01373
01374 CopyMandatoryEntry(0x0002,0x0012,Util::CreateUniqueUID());
01375
01376
01377 std::string version = "GDCM ";
01378 version += Util::GetVersion();
01379 CopyMandatoryEntry(0x0002,0x0013,version);
01380 }
01381
01382
01383 Archive->Push(0x0028,0x0015);
01384 Archive->Push(0x0028,0x0016);
01385 Archive->Push(0x0028,0x0017);
01386 Archive->Push(0x0028,0x00199);
01387
01388
01389
01390 if ( FileInternal->GetEntryString(0x0028,0x0100) == "12")
01391 {
01392 CopyMandatoryEntry(0x0028,0x0100,"16");
01393 }
01394
01395
01396
01397 std::ostringstream s;
01398
01399 int nbBitsAllocated = FileInternal->GetBitsAllocated();
01400 if ( nbBitsAllocated == 0 || nbBitsAllocated > 32)
01401 {
01402 CopyMandatoryEntry(0x0028,0x0100,"16");
01403 gdcmWarningMacro("(0028,0100) changed from "
01404 << nbBitsAllocated << " to 16 for consistency purpose");
01405 nbBitsAllocated = 16;
01406 }
01407
01408 int nbBitsStored = FileInternal->GetBitsStored();
01409 if ( nbBitsStored == 0 || nbBitsStored > nbBitsAllocated )
01410 {
01411 s.str("");
01412 s << nbBitsAllocated;
01413 CopyMandatoryEntry(0x0028,0x0101,s.str());
01414 gdcmWarningMacro("(0028,0101) changed from "
01415 << nbBitsStored << " to " << nbBitsAllocated
01416 << " for consistency purpose" );
01417 nbBitsStored = nbBitsAllocated;
01418 }
01419
01420 int highBitPosition = FileInternal->GetHighBitPosition();
01421 if ( highBitPosition == 0 ||
01422 highBitPosition > nbBitsAllocated-1 ||
01423 highBitPosition < nbBitsStored-1 )
01424 {
01425 s.str("");
01426 s << nbBitsStored - 1;
01427 CopyMandatoryEntry(0x0028,0x0102,s.str());
01428 gdcmWarningMacro("(0028,0102) changed from "
01429 << highBitPosition << " to " << nbBitsAllocated-1
01430 << " for consistency purpose");
01431 }
01432
01433 std::string pixelSpacing = FileInternal->GetEntryString(0x0028,0x0030);
01434 if ( pixelSpacing == GDCM_UNFOUND )
01435 {
01436 pixelSpacing = "1.0\\1.0";
01437
01438 CopyMandatoryEntry(0x0028,0x0030,pixelSpacing);
01439 }
01440
01441
01442
01443
01444
01445 CheckMandatoryEntry(0x0018,0x1164,pixelSpacing);
01446
01447
01448 CheckMandatoryEntry(0x0028,0x0002,"1");
01449
01450
01451
01452
01453
01454
01455
01456 DataEntry *e_0008_0016 = FileInternal->GetDataEntry(0x0008, 0x0016);
01457 if ( e_0008_0016 )
01458 {
01459
01460 SeqEntry *sis = SeqEntry::New (
01461 Global::GetDicts()->GetDefaultPubDict()->GetEntry(0x0008, 0x2112) );
01462 SQItem *sqi = SQItem::New(1);
01463
01464
01465 DataEntry *e_0008_1150 = DataEntry::New(
01466 Global::GetDicts()->GetDefaultPubDict()->GetEntry(0x0008, 0x1150) );
01467 e_0008_1150->SetString( e_0008_0016->GetString());
01468 sqi->AddEntry(e_0008_1150);
01469 e_0008_1150->Delete();
01470
01471
01472 DataEntry *e_0008_0018 = FileInternal->GetDataEntry(0x0008, 0x0018);
01473 DataEntry *e_0008_1155 = DataEntry::New(
01474 Global::GetDicts()->GetDefaultPubDict()->GetEntry(0x0008, 0x1155) );
01475 e_0008_1155->SetString( e_0008_0018->GetString());
01476 sqi->AddEntry(e_0008_1155);
01477 e_0008_1155->Delete();
01478
01479 sis->AddSQItem(sqi,1);
01480 sqi->Delete();
01481
01482
01483 Archive->Push(sis);
01484 sis->Delete();
01485
01486
01487 if ( KeepMediaStorageSOPClassUID)
01488
01489
01490
01491 CheckMandatoryEntry(0x0008,0x0008,"DERIVED\\PRIMARY");
01492 else
01493
01494
01495 CopyMandatoryEntry(0x0008,0x0008,"DERIVED\\PRIMARY");
01496
01497 }
01498
01499
01500
01501
01502 CopyMandatoryEntry(0x0008,0x0018,sop);
01503
01504
01505
01506
01507
01508
01509 if ( KeepMediaStorageSOPClassUID)
01510 {
01511
01512
01513 CheckMandatoryEntry(0x0008,0x0016,"1.2.840.10008.5.1.4.1.1.7");
01514 }
01515 else
01516 {
01517
01518
01519 CopyMandatoryEntry(0x0008,0x0016,"1.2.840.10008.5.1.4.1.1.7");
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540 CheckMandatoryEntry(0x0008,0x0064,"SYN");
01541 }
01542
01543
01544
01545
01546
01547
01548
01549 const std::string &date = Util::GetCurrentDate();
01550 CopyMandatoryEntry(0x0008,0x0012,date);
01551
01552
01553 const std::string &time = Util::GetCurrentTime();
01554 CopyMandatoryEntry(0x0008,0x0013,time);
01555
01556
01557 CheckMandatoryEntry(0x0008,0x0020,date);
01558
01559 CheckMandatoryEntry(0x0008,0x0030,time);
01560
01561
01562
01563 CheckMandatoryEntry(0x0008,0x0050,"");
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580
01581 CheckMandatoryEntry(0x0020,0x000d,Util::CreateUniqueUID());
01582
01583
01584
01585
01586
01587
01588
01589 CheckMandatoryEntry(0x0020,0x000e,Util::CreateUniqueUID());
01590
01591
01592 CheckMandatoryEntry(0x0020,0x0010,"");
01593
01594
01595 CheckMandatoryEntry(0x0020,0x0011,"");
01596
01597
01598 CheckMandatoryEntry(0x0020,0x0013,"");
01599
01600
01601
01602 gdcm::Orientation *o = gdcm::Orientation::New();
01603 std::string ori = o->GetOrientation ( FileInternal );
01604 o->Delete();
01605 if (ori != "\\" )
01606 CheckMandatoryEntry(0x0020,0x0020,ori);
01607 else
01608 CheckMandatoryEntry(0x0020,0x0020,"");
01609
01610
01611 CheckMandatoryEntry(0x0008,0x0060,"OT");
01612
01613
01614 CheckMandatoryEntry(0x0008,0x0070,"GDCM Factory");
01615
01616
01617 CheckMandatoryEntry(0x0008,0x0080,"GDCM Hospital");
01618
01619
01620 CheckMandatoryEntry(0x0010,0x0010,"GDCM^Patient");
01621
01622
01623 CheckMandatoryEntry(0x0010,0x0020,"");
01624
01625
01626 CheckMandatoryEntry(0x0010,0x0030,"");
01627
01628
01629 CheckMandatoryEntry(0x0010,0x0040,"");
01630
01631
01632 CheckMandatoryEntry(0x0008,0x0090,"");
01633
01634
01635
01636
01637
01638
01639 DataEntry *e_0028_0008 = FileInternal->GetDataEntry(0x0028, 0x0008);
01640 if ( !e_0028_0008 )
01641 {
01642 Archive->Push(0x0020, 0x0052);
01643 }
01644
01645
01646
01647
01648
01649
01650
01651
01652
01653
01654
01655
01656
01657
01658
01659
01660
01661
01662 }
01663
01664 void FileHelper::CheckMandatoryEntry(uint16_t group,uint16_t elem,std::string value)
01665 {
01666 DataEntry *entry = FileInternal->GetDataEntry(group,elem);
01667 if ( !entry )
01668 {
01669 entry = DataEntry::New(Global::GetDicts()->GetDefaultPubDict()->GetEntry(group,elem));
01670 entry->SetString(value);
01671 Archive->Push(entry);
01672 entry->Delete();
01673 }
01674 }
01675
01676 void FileHelper::SetMandatoryEntry(uint16_t group,uint16_t elem,std::string value)
01677 {
01678 DataEntry *entry = DataEntry::New(Global::GetDicts()->GetDefaultPubDict()->GetEntry(group,elem));
01679 entry->SetString(value);
01680 Archive->Push(entry);
01681 entry->Delete();
01682 }
01683
01684 void FileHelper::CopyMandatoryEntry(uint16_t group,uint16_t elem,std::string value)
01685 {
01686 DataEntry *entry = CopyDataEntry(group,elem);
01687 entry->SetString(value);
01688 Archive->Push(entry);
01689 entry->Delete();
01690 }
01691
01695 void FileHelper::RestoreWriteMandatory()
01696 {
01697
01698 Archive->Restore(0x0002,0x0000);
01699 Archive->Restore(0x0002,0x0001);
01700 Archive->Restore(0x0002,0x0002);
01701 Archive->Restore(0x0002,0x0003);
01702 Archive->Restore(0x0002,0x0010);
01703 Archive->Restore(0x0002,0x0012);
01704 Archive->Restore(0x0002,0x0013);
01705 Archive->Restore(0x0002,0x0016);
01706 Archive->Restore(0x0002,0x0100);
01707 Archive->Restore(0x0002,0x0102);
01708
01709
01710
01711 Archive->Restore(0x0008,0x0012);
01712 Archive->Restore(0x0008,0x0013);
01713 Archive->Restore(0x0008,0x0016);
01714 Archive->Restore(0x0008,0x0018);
01715 Archive->Restore(0x0008,0x0060);
01716 Archive->Restore(0x0008,0x0070);
01717 Archive->Restore(0x0008,0x0080);
01718 Archive->Restore(0x0008,0x0090);
01719 Archive->Restore(0x0008,0x2112);
01720
01721 Archive->Restore(0x0010,0x0010);
01722 Archive->Restore(0x0010,0x0030);
01723 Archive->Restore(0x0010,0x0040);
01724
01725 Archive->Restore(0x0020,0x000d);
01726 Archive->Restore(0x0020,0x000e);
01727 }
01728
01729
01733 void FileHelper::CallStartMethod()
01734 {
01735 Progress = 0.0f;
01736 Abort = false;
01737 CommandManager::ExecuteCommand(this,CMD_STARTPROGRESS);
01738 }
01739
01743 void FileHelper::CallProgressMethod()
01744 {
01745 CommandManager::ExecuteCommand(this,CMD_PROGRESS);
01746 }
01747
01751 void FileHelper::CallEndMethod()
01752 {
01753 Progress = 1.0f;
01754 CommandManager::ExecuteCommand(this,CMD_ENDPROGRESS);
01755 }
01756
01757
01758
01762 void FileHelper::Initialize()
01763 {
01764 UserFunction = 0;
01765 KeepMediaStorageSOPClassUID = false;
01766
01767 WriteMode = WMODE_RAW;
01768 WriteType = ExplicitVR;
01769
01770 PixelReadConverter = new PixelReadConvert;
01771 PixelWriteConverter = new PixelWriteConvert;
01772 Archive = new DocEntryArchive( FileInternal );
01773 }
01774
01781 uint8_t *FileHelper::GetRaw()
01782 {
01783 PixelReadConverter->SetUserFunction( UserFunction );
01784
01785 uint8_t *raw = PixelReadConverter->GetRaw();
01786 if ( ! raw )
01787 {
01788
01789 std::ifstream *fp = FileInternal->OpenFile();
01790 PixelReadConverter->ReadAndDecompressPixelData( fp );
01791 if ( fp )
01792 FileInternal->CloseFile();
01793
01794 raw = PixelReadConverter->GetRaw();
01795 if ( ! raw )
01796 {
01797 gdcmWarningMacro( "Read/decompress of pixel data apparently went wrong.");
01798 return 0;
01799 }
01800 }
01801 return raw;
01802 }
01803
01804
01810 void FileHelper::Print(std::ostream &os, std::string const &)
01811 {
01812 FileInternal->SetPrintLevel(PrintLevel);
01813 FileInternal->Print(os);
01814
01815 if ( FileInternal->IsReadable() )
01816 {
01817 PixelReadConverter->SetPrintLevel(PrintLevel);
01818 PixelReadConverter->Print(os);
01819 }
01820 }
01821
01822
01823 }