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 "gdcmDocEntry.h"
00030 #include "gdcmFile.h"
00031 #include "gdcmPixelReadConvert.h"
00032 #include "gdcmPixelWriteConvert.h"
00033 #include "gdcmDocEntryArchive.h"
00034 #include "gdcmDictSet.h"
00035 #include "gdcmOrientation.h"
00036
00037 #if defined(__BORLANDC__)
00038 #include <mem.h>
00039 #endif
00040
00041 #include <fstream>
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
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157 namespace GDCM_NAME_SPACE
00158 {
00159 typedef std::map<uint16_t, int> GroupHT;
00160
00161
00175 FileHelper::FileHelper( )
00176 {
00177 FileInternal = File::New( );
00178 Initialize();
00179 }
00180
00195 FileHelper::FileHelper(File *header)
00196 {
00197 gdcmAssertMacro(header);
00198
00199 FileInternal = header;
00200 FileInternal->Register();
00201 Initialize();
00202 if ( FileInternal->IsReadable() )
00203 {
00204 PixelReadConverter->GrabInformationsFromFile( FileInternal, this );
00205 }
00206 }
00207
00213 FileHelper::~FileHelper()
00214 {
00215 if ( PixelReadConverter )
00216 {
00217 delete PixelReadConverter;
00218 }
00219 if ( PixelWriteConverter )
00220 {
00221 delete PixelWriteConverter;
00222 }
00223 if ( Archive )
00224 {
00225 delete Archive;
00226 }
00227
00228 FileInternal->Unregister();
00229 }
00230
00231
00232
00233
00242 void FileHelper::SetLoadMode(int loadMode)
00243 {
00244 GetFile()->SetLoadMode( loadMode );
00245 }
00250 void FileHelper::SetFileName(std::string const &fileName)
00251 {
00252 FileInternal->SetFileName( fileName );
00253 }
00254
00260 bool FileHelper::Load()
00261 {
00262 if ( !FileInternal->Load() )
00263 return false;
00264
00265 PixelReadConverter->GrabInformationsFromFile( FileInternal, this );
00266 return true;
00267 }
00268
00277 bool FileHelper::SetEntryString(std::string const &content,
00278 uint16_t group, uint16_t elem)
00279 {
00280 return FileInternal->SetEntryString(content, group, elem);
00281 }
00282
00283
00293 bool FileHelper::SetEntryBinArea(uint8_t *content, int lgth,
00294 uint16_t group, uint16_t elem)
00295 {
00296 return FileInternal->SetEntryBinArea(content, lgth, group, elem);
00297 }
00298
00309 DataEntry *FileHelper::InsertEntryString(std::string const &content,
00310 uint16_t group, uint16_t elem,
00311 VRKey const &vr )
00312 {
00313 return FileInternal->InsertEntryString(content, group, elem, vr);
00314 }
00315
00328 DataEntry *FileHelper::InsertEntryBinArea(uint8_t *binArea, int lgth,
00329 uint16_t group, uint16_t elem,
00330 VRKey const &vr )
00331 {
00332 return FileInternal->InsertEntryBinArea(binArea, lgth, group, elem, vr);
00333 }
00334
00343 SeqEntry *FileHelper::InsertSeqEntry(uint16_t group, uint16_t elem)
00344 {
00345 return FileInternal->InsertSeqEntry(group, elem);
00346 }
00347
00356 size_t FileHelper::GetImageDataSize()
00357 {
00358 if ( PixelWriteConverter->GetUserData() )
00359 {
00360 return PixelWriteConverter->GetUserDataSize();
00361 }
00362 return PixelReadConverter->GetRGBSize();
00363 }
00364
00372 size_t FileHelper::GetImageDataRawSize()
00373 {
00374 if ( PixelWriteConverter->GetUserData() )
00375 {
00376 return PixelWriteConverter->GetUserDataSize();
00377 }
00378 return PixelReadConverter->GetRawSize();
00379 }
00380
00393 uint8_t *FileHelper::GetImageData()
00394 {
00395 if ( PixelWriteConverter->GetUserData() )
00396 {
00397 return PixelWriteConverter->GetUserData();
00398 }
00399
00400 if ( ! GetRaw() )
00401 {
00402
00403 return 0;
00404 }
00405
00406 if ( FileInternal->HasLUT() && PixelReadConverter->BuildRGBImage() )
00407 {
00408 return PixelReadConverter->GetRGB();
00409 }
00410 else
00411 {
00412
00413 return PixelReadConverter->GetRaw();
00414 }
00415 }
00416
00428 uint8_t *FileHelper::GetImageDataRaw ()
00429 {
00430 return GetRaw();
00431 }
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00509 void FileHelper::SetImageData(uint8_t *inData, size_t expectedSize)
00510 {
00511 PixelWriteConverter->SetUserData(inData, expectedSize);
00512 }
00513
00522 void FileHelper::SetUserData(uint8_t *inData, size_t expectedSize)
00523 {
00524 if( WriteType == JPEG2000 )
00525 {
00526 PixelWriteConverter->SetCompressJPEG2000UserData(inData, expectedSize, FileInternal);
00527 }
00528 else if( WriteType == JPEG )
00529 {
00530 PixelWriteConverter->SetCompressJPEGUserData(inData, expectedSize, FileInternal);
00531 }
00532 else
00533 {
00534 PixelWriteConverter->SetUserData(inData, expectedSize);
00535 }
00536 }
00537
00542 uint8_t *FileHelper::GetUserData()
00543 {
00544 return PixelWriteConverter->GetUserData();
00545 }
00546
00551 size_t FileHelper::GetUserDataSize()
00552 {
00553 return PixelWriteConverter->GetUserDataSize();
00554 }
00555
00560 uint8_t *FileHelper::GetRGBData()
00561 {
00562 return PixelReadConverter->GetRGB();
00563 }
00564
00569 size_t FileHelper::GetRGBDataSize()
00570 {
00571 return PixelReadConverter->GetRGBSize();
00572 }
00573
00578 uint8_t *FileHelper::GetRawData()
00579 {
00580 return PixelReadConverter->GetRaw();
00581 }
00582
00587 size_t FileHelper::GetRawDataSize()
00588 {
00589 return PixelReadConverter->GetRawSize();
00590 }
00591
00595 uint8_t* FileHelper::GetLutRGBA()
00596 {
00597 if ( PixelReadConverter->GetLutRGBA() ==0 )
00598 PixelReadConverter->BuildLUTRGBA();
00599 return PixelReadConverter->GetLutRGBA();
00600 }
00601
00605 int FileHelper::GetLutItemNumber()
00606 {
00607 return PixelReadConverter->GetLutItemNumber();
00608 }
00609
00613 int FileHelper::GetLutItemSize()
00614 {
00615 return PixelReadConverter->GetLutItemSize();
00616 }
00617
00626 bool FileHelper::WriteRawData(std::string const &fileName)
00627 {
00628 std::ofstream fp1(fileName.c_str(), std::ios::out | std::ios::binary );
00629 if (!fp1)
00630 {
00631 gdcmWarningMacro( "Fail to open (write) file:" << fileName.c_str());
00632 return false;
00633 }
00634
00635 if ( PixelWriteConverter->GetUserData() )
00636 {
00637 fp1.write( (char *)PixelWriteConverter->GetUserData(),
00638 PixelWriteConverter->GetUserDataSize() );
00639 }
00640 else if ( PixelReadConverter->GetRGB() )
00641 {
00642 fp1.write( (char *)PixelReadConverter->GetRGB(),
00643 PixelReadConverter->GetRGBSize());
00644 }
00645 else if ( PixelReadConverter->GetRaw() )
00646 {
00647 fp1.write( (char *)PixelReadConverter->GetRaw(),
00648 PixelReadConverter->GetRawSize());
00649 }
00650 else
00651 {
00652 gdcmErrorMacro( "Nothing written." );
00653 }
00654
00655 fp1.close();
00656
00657 return true;
00658 }
00659
00669 bool FileHelper::WriteDcmImplVR (std::string const &fileName)
00670 {
00671 SetWriteTypeToDcmImplVR();
00672 return Write(fileName);
00673 }
00674
00684 bool FileHelper::WriteDcmExplVR (std::string const &fileName)
00685 {
00686 SetWriteTypeToDcmExplVR();
00687 return Write(fileName);
00688 }
00689
00704 bool FileHelper::WriteAcr (std::string const &fileName)
00705 {
00706 SetWriteTypeToAcr();
00707 return Write(fileName);
00708 }
00709
00716 bool FileHelper::Write(std::string const &fileName)
00717 {
00718 CheckMandatoryElements();
00719
00720 bool flag = false;
00721 DocEntry *e;
00722 switch(WriteType)
00723 {
00724 case ImplicitVR:
00725 SetWriteFileTypeToImplicitVR();
00726 break;
00727
00728 case Unknown:
00729 case ExplicitVR:
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762 SetWriteFileTypeToExplicitVR();
00763
00764 break;
00765 case ACR:
00766 case ACR_LIBIDO:
00767
00768
00769
00770
00771
00772
00773 if ( ! FileInternal->GetDataEntry(0x0008, 0x0010) )
00774 FileInternal->InsertEntryString("ACR-NEMA V1.0 ",
00775 0x0008, 0x0010, "LO");
00776 SetWriteFileTypeToACR();
00777
00778 break;
00779
00781 case JPEG:
00782 SetWriteFileTypeToJPEG();
00783 break;
00784
00785 case JPEG2000:
00786 SetWriteFileTypeToJPEG2000();
00787 break;
00788 }
00789
00790
00791
00792
00793
00794
00795
00798
00799 if ( WriteType == ACR_LIBIDO )
00800 {
00801 SetWriteToLibido();
00802 }
00803 else
00804 {
00805 SetWriteToNoLibido();
00806 }
00807
00808
00809 switch(WriteMode)
00810 {
00811 case WMODE_RAW :
00812 SetWriteToRaw();
00813 break;
00814 case WMODE_RGB :
00815 SetWriteToRGB();
00816 break;
00817 }
00818
00819 bool check;
00820 if (WriteType == JPEG || WriteType == JPEG2000)
00821 check = true;
00822 else
00823 check = CheckWriteIntegrity();
00824
00825 if (check)
00826 {
00827 check = FileInternal->Write(fileName,WriteType);
00828 }
00829
00830 RestoreWrite();
00831
00832
00833
00834
00835
00836
00837
00838
00839 RestoreWriteOfLibido();
00840
00841
00842 return check;
00843 }
00844
00845
00846
00851 bool FileHelper::CheckWriteIntegrity()
00852 {
00853 if ( PixelWriteConverter->GetUserData() )
00854 {
00855 int numberBitsAllocated = FileInternal->GetBitsAllocated();
00856 if ( numberBitsAllocated == 0 || numberBitsAllocated == 12 )
00857 {
00858 gdcmWarningMacro( "numberBitsAllocated changed from "
00859 << numberBitsAllocated << " to 16 "
00860 << " for consistency purpose" );
00861 numberBitsAllocated = 16;
00862 }
00863
00864 size_t decSize = FileInternal->GetXSize()
00865 * FileInternal->GetYSize()
00866 * FileInternal->GetZSize()
00867 * FileInternal->GetTSize()
00868 * FileInternal->GetSamplesPerPixel()
00869 * ( numberBitsAllocated / 8 );
00870 size_t rgbSize = decSize;
00871 if ( FileInternal->HasLUT() )
00872 rgbSize = decSize * 3;
00873
00874 switch(WriteMode)
00875 {
00876 case WMODE_RAW :
00877 if ( decSize!=PixelWriteConverter->GetUserDataSize() )
00878 {
00879 gdcmWarningMacro( "Data size (Raw) is incorrect. Should be "
00880 << decSize << " / Found :"
00881 << PixelWriteConverter->GetUserDataSize() );
00882 return false;
00883 }
00884 break;
00885 case WMODE_RGB :
00886 if ( rgbSize!=PixelWriteConverter->GetUserDataSize() )
00887 {
00888 gdcmWarningMacro( "Data size (RGB) is incorrect. Should be "
00889 << decSize << " / Found "
00890 << PixelWriteConverter->GetUserDataSize() );
00891 return false;
00892 }
00893 break;
00894 }
00895 }
00896 return true;
00897 }
00898
00906 void FileHelper::SetWriteToRaw()
00907 {
00908 if ( FileInternal->GetNumberOfScalarComponents() == 3
00909 && !FileInternal->HasLUT() )
00910 {
00911 SetWriteToRGB();
00912 }
00913 else
00914 {
00915
00916 DataEntry *photInt = CopyDataEntry(0x0028,0x0004,"CS");
00917 if (FileInternal->HasLUT() )
00918 {
00919 photInt->SetString("PALETTE COLOR ");
00920 }
00921 else
00922 {
00923 if (GetPhotometricInterpretation() == 2)
00924 photInt->SetString("MONOCHROME2 ");
00925 else
00926 photInt->SetString("MONOCHROME1 ");
00927 }
00928
00929 PixelWriteConverter->SetReadData(PixelReadConverter->GetRaw(),
00930 PixelReadConverter->GetRawSize());
00931
00932 std::string vr = "OB";
00933 if ( FileInternal->GetBitsAllocated()>8 )
00934 vr = "OW";
00935 if ( FileInternal->GetBitsAllocated()==24 )
00936 vr = "OB";
00937
00938 if( WriteType == JPEG || WriteType == JPEG2000)
00939 {
00940 vr = "OW";
00941 }
00942
00943 DataEntry *pixel =
00944 CopyDataEntry(GetFile()->GetGrPixel(),GetFile()->GetNumPixel(),vr);
00945 pixel->SetFlag(DataEntry::FLAG_PIXELDATA);
00946 pixel->SetBinArea(PixelWriteConverter->GetData(),false);
00947 pixel->SetLength(
00948 static_cast< uint32_t >(PixelWriteConverter->GetDataSize()) );
00949
00950 if (!FileInternal->HasLUT() && GetPhotometricInterpretation() == 1)
00951 {
00952 ConvertFixGreyLevels( pixel->GetBinArea(), pixel->GetLength() );
00953 }
00954
00955 Archive->Push(photInt);
00956 Archive->Push(pixel);
00957
00958 photInt->Delete();
00959 pixel->Delete();
00960 }
00961 }
00962
00970 void FileHelper::SetWriteToRGB()
00971 {
00972 if ( FileInternal->GetNumberOfScalarComponents()==3 )
00973 {
00974 PixelReadConverter->BuildRGBImage();
00975
00976 DataEntry *spp = CopyDataEntry(0x0028,0x0002,"US");
00977 spp->SetString("3 ");
00978
00979 DataEntry *planConfig = CopyDataEntry(0x0028,0x0006,"US");
00980 planConfig->SetString("0 ");
00981
00982 DataEntry *photInt = CopyDataEntry(0x0028,0x0004,"CS");
00983 photInt->SetString("RGB ");
00984
00985 if ( PixelReadConverter->GetRGB() )
00986 {
00987 PixelWriteConverter->SetReadData(PixelReadConverter->GetRGB(),
00988 PixelReadConverter->GetRGBSize());
00989 }
00990 else
00991 {
00992 PixelWriteConverter->SetReadData(PixelReadConverter->GetRaw(),
00993 PixelReadConverter->GetRawSize());
00994 }
00995
00996 std::string vr = "OB";
00997 if ( FileInternal->GetBitsAllocated()>8 )
00998 vr = "OW";
00999 if ( FileInternal->GetBitsAllocated()==24 )
01000 vr = "OB";
01001 DataEntry *pixel =
01002 CopyDataEntry(GetFile()->GetGrPixel(),GetFile()->GetNumPixel(),vr);
01003 pixel->SetFlag(DataEntry::FLAG_PIXELDATA);
01004 pixel->SetBinArea(PixelWriteConverter->GetData(),false);
01005 pixel->SetLength(PixelWriteConverter->GetDataSize());
01006
01007 Archive->Push(spp);
01008 Archive->Push(planConfig);
01009 Archive->Push(photInt);
01010 Archive->Push(pixel);
01011
01012 spp->Delete();
01013 planConfig->Delete();
01014 photInt->Delete();
01015 pixel->Delete();
01016
01017
01018 Archive->Push(0x0028,0x1101);
01019 Archive->Push(0x0028,0x1102);
01020 Archive->Push(0x0028,0x1103);
01021 Archive->Push(0x0028,0x1201);
01022 Archive->Push(0x0028,0x1202);
01023 Archive->Push(0x0028,0x1203);
01024
01025
01026 Archive->Push(0x0028,0x1199);
01027
01028
01029
01030
01031 if ( FileInternal->GetBitsAllocated()==24 )
01032 {
01033 DataEntry *bitsAlloc = CopyDataEntry(0x0028,0x0100,"US");
01034 bitsAlloc->SetString("8 ");
01035
01036 DataEntry *bitsStored = CopyDataEntry(0x0028,0x0101,"US");
01037 bitsStored->SetString("8 ");
01038
01039 DataEntry *highBit = CopyDataEntry(0x0028,0x0102,"US");
01040 highBit->SetString("7 ");
01041
01042 Archive->Push(bitsAlloc);
01043 Archive->Push(bitsStored);
01044 Archive->Push(highBit);
01045
01046 bitsAlloc->Delete();
01047 bitsStored->Delete();
01048 highBit->Delete();
01049 }
01050 }
01051 else
01052 {
01053 SetWriteToRaw();
01054 }
01055 }
01056
01060 void FileHelper::RestoreWrite()
01061 {
01062 Archive->Restore(0x0028,0x0002);
01063 Archive->Restore(0x0028,0x0004);
01064
01065 Archive->Restore(0x0028,0x0006);
01066 Archive->Restore(GetFile()->GetGrPixel(),GetFile()->GetNumPixel());
01067
01068
01069 Archive->Restore(0x0028,0x0100);
01070 Archive->Restore(0x0028,0x0101);
01071 Archive->Restore(0x0028,0x0102);
01072
01073
01074 Archive->Restore(0x0028,0x1101);
01075 Archive->Restore(0x0028,0x1102);
01076 Archive->Restore(0x0028,0x1103);
01077 Archive->Restore(0x0028,0x1201);
01078 Archive->Restore(0x0028,0x1202);
01079 Archive->Restore(0x0028,0x1203);
01080
01081
01082 Archive->Restore(0x0028,0x1203);
01083
01084
01085 Archive->Restore(0x0002,0x0000);
01086 Archive->Restore(0x0002,0x0001);
01087 Archive->Restore(0x0002,0x0002);
01088 Archive->Restore(0x0002,0x0003);
01089 Archive->Restore(0x0002,0x0010);
01090 Archive->Restore(0x0002,0x0012);
01091 Archive->Restore(0x0002,0x0013);
01092 Archive->Restore(0x0002,0x0016);
01093 Archive->Restore(0x0002,0x0100);
01094 Archive->Restore(0x0002,0x0102);
01095
01096 }
01097
01105 void FileHelper::SetWriteFileTypeToACR()
01106 {
01107 Archive->Push(0x0002,0x0000);
01108 Archive->Push(0x0002,0x0001);
01109 Archive->Push(0x0002,0x0002);
01110 Archive->Push(0x0002,0x0003);
01111 Archive->Push(0x0002,0x0010);
01112 Archive->Push(0x0002,0x0012);
01113 Archive->Push(0x0002,0x0013);
01114 Archive->Push(0x0002,0x0016);
01115 Archive->Push(0x0002,0x0100);
01116 Archive->Push(0x0002,0x0102);
01117 }
01118
01122 void FileHelper::SetWriteFileTypeToJPEG2000()
01123 {
01124 std::string ts = Util::DicomString(
01125 Global::GetTS()->GetSpecialTransferSyntax(TS::JPEG2000Lossless) );
01126
01127 DataEntry *tss = CopyDataEntry(0x0002,0x0010,"UI");
01128 tss->SetString(ts);
01129
01130 Archive->Push(tss);
01131 tss->Delete();
01132 }
01133
01137 void FileHelper::SetWriteFileTypeToJPEG()
01138 {
01139 std::string ts = Util::DicomString(
01140 Global::GetTS()->GetSpecialTransferSyntax(TS::JPEGLosslessProcess14_1) );
01141
01142 DataEntry *tss = CopyDataEntry(0x0002,0x0010,"UI");
01143 tss->SetString(ts);
01144
01145 Archive->Push(tss);
01146 tss->Delete();
01147 }
01148
01152 void FileHelper::SetWriteFileTypeToExplicitVR()
01153 {
01154 std::string ts = Util::DicomString(
01155 Global::GetTS()->GetSpecialTransferSyntax(TS::ExplicitVRLittleEndian) );
01156
01157 DataEntry *tss = CopyDataEntry(0x0002,0x0010,"UI");
01158 tss->SetString(ts);
01159 Archive->Push(tss);
01160 tss->Delete();
01161 }
01162
01166 void FileHelper::SetWriteFileTypeToImplicitVR()
01167 {
01168 std::string ts = Util::DicomString(
01169 Global::GetTS()->GetSpecialTransferSyntax(TS::ImplicitVRLittleEndian) );
01170
01171 DataEntry *tss = CopyDataEntry(0x0002,0x0010,"UI");
01172 tss->SetString(ts);
01173 Archive->Push(tss);
01174 tss->Delete();
01175 }
01176
01180 void FileHelper::SetWriteToLibido()
01181 {
01182 DataEntry *oldRow = FileInternal->GetDataEntry(0x0028, 0x0010);
01183 DataEntry *oldCol = FileInternal->GetDataEntry(0x0028, 0x0011);
01184
01185 if ( oldRow && oldCol )
01186 {
01187 std::string rows, columns;
01188
01189 DataEntry *newRow=DataEntry::New(0x0028, 0x0010, "US");
01190 DataEntry *newCol=DataEntry::New(0x0028, 0x0011, "US");
01191
01192 newRow->Copy(oldCol);
01193 newCol->Copy(oldRow);
01194
01195 newRow->SetString(oldCol->GetString());
01196 newCol->SetString(oldRow->GetString());
01197
01198 Archive->Push(newRow);
01199 Archive->Push(newCol);
01200
01201 newRow->Delete();
01202 newCol->Delete();
01203 }
01204
01205 DataEntry *libidoCode = CopyDataEntry(0x0008,0x0010,"LO");
01206 libidoCode->SetString("ACRNEMA_LIBIDO_1.1");
01207 Archive->Push(libidoCode);
01208 libidoCode->Delete();
01209 }
01210
01214 void FileHelper::SetWriteToNoLibido()
01215 {
01216 DataEntry *recCode = FileInternal->GetDataEntry(0x0008,0x0010);
01217 if ( recCode )
01218 {
01219 if ( recCode->GetString() == "ACRNEMA_LIBIDO_1.1" )
01220 {
01221 DataEntry *libidoCode = CopyDataEntry(0x0008,0x0010,"LO");
01222 libidoCode->SetString("");
01223 Archive->Push(libidoCode);
01224 libidoCode->Delete();
01225 }
01226 }
01227 }
01228
01232 void FileHelper::RestoreWriteOfLibido()
01233 {
01234 Archive->Restore(0x0028,0x0010);
01235 Archive->Restore(0x0028,0x0011);
01236 Archive->Restore(0x0008,0x0010);
01237
01238
01239 Archive->Restore(0x0028,0x0015);
01240 Archive->Restore(0x0028,0x0016);
01241 Archive->Restore(0x0028,0x0017);
01242 Archive->Restore(0x0028,0x00199);
01243 }
01244
01252 DataEntry *FileHelper::CopyDataEntry(uint16_t group, uint16_t elem,
01253 const VRKey &vr)
01254 {
01255 DocEntry *oldE = FileInternal->GetDocEntry(group, elem);
01256 DataEntry *newE;
01257
01258 if ( oldE && vr != GDCM_VRUNKNOWN )
01259 if ( oldE->GetVR() != vr )
01260 oldE = NULL;
01261
01262 if ( oldE )
01263 {
01264 newE = DataEntry::New(group, elem, vr);
01265 newE->Copy(oldE);
01266 }
01267 else
01268 {
01269 newE = GetFile()->NewDataEntry(group, elem, vr);
01270 }
01271
01272 return newE;
01273 }
01274
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448 void FileHelper::CheckMandatoryElements()
01449 {
01450 std::string sop = Util::CreateUniqueUID();
01451
01452
01453
01454 if ( WriteType != ACR && WriteType != ACR_LIBIDO )
01455 {
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470 Archive->Push(0x0008,0x0001);
01471 Archive->Push(0x0008,0x0010);
01472 Archive->Push(0x0028,0x0005);
01473
01474
01475
01476
01477 CopyMandatoryEntry(0x0002,0x0000,"0","UL");
01478
01479 DataEntry *e_0002_0001 = CopyDataEntry(0x0002,0x0001, "OB");
01480 e_0002_0001->SetBinArea((uint8_t*)Util::GetFileMetaInformationVersion(),
01481 false);
01482 e_0002_0001->SetLength(2);
01483 Archive->Push(e_0002_0001);
01484 e_0002_0001->Delete();
01485
01486 if ( ContentType == FILTERED_IMAGE || ContentType == UNMODIFIED_PIXELS_IMAGE)
01487 {
01488
01489 CheckMandatoryEntry(0x0002,0x0002,"1.2.840.10008.5.1.4.1.1.7","UI");
01490 }
01491 else
01492 {
01493
01494
01495 CopyMandatoryEntry(0x0002,0x0002,"1.2.840.10008.5.1.4.1.1.7","UI");
01496 }
01497
01498
01499 CopyMandatoryEntry(0x0002,0x0003,sop,"UI");
01500
01501
01502
01503
01504 CopyMandatoryEntry(0x0002,0x0012,Util::CreateUniqueUID(),"UI");
01505
01506
01507 std::string version = "GDCM ";
01508 version += Util::GetVersion();
01509 CopyMandatoryEntry(0x0002,0x0013,version,"SH");
01510 }
01511
01512
01513
01514 if ( ContentType != USER_OWN_IMAGE)
01515 {
01516
01517 gdcmDebugMacro( "USER_OWN_IMAGE (1)");
01518
01519
01520
01521
01522 DataEntry *e_0008_0016 = FileInternal->GetDataEntry(0x0008, 0x0016);
01523 if ( e_0008_0016 )
01524 {
01525
01526
01527
01528 SeqEntry *sis = SeqEntry::New (0x0008, 0x2112);
01529 SQItem *sqi = SQItem::New(1);
01530
01531
01532
01533
01534 DataEntry *e_0008_1150 = DataEntry::New(0x0008, 0x1150, "UI");
01535 e_0008_1150->SetString( e_0008_0016->GetString());
01536 sqi->AddEntry(e_0008_1150);
01537 e_0008_1150->Delete();
01538
01539
01540 DataEntry *e_0008_0018 = FileInternal->GetDataEntry(0x0008, 0x0018);
01541
01542
01543 DataEntry *e_0008_1155 = DataEntry::New(0x0008, 0x1155, "UI");
01544 e_0008_1155->SetString( e_0008_0018->GetString());
01545 sqi->AddEntry(e_0008_1155);
01546 e_0008_1155->Delete();
01547
01548 sis->AddSQItem(sqi,1);
01549 sqi->Delete();
01550
01551
01552 Archive->Push(sis);
01553 sis->Delete();
01554
01555
01556 if ( ContentType == FILTERED_IMAGE)
01557
01558
01559 CopyMandatoryEntry(0x0008,0x0008,"DERIVED\\PRIMARY","CS");
01560 }
01561 }
01562
01563 if ( ContentType == FILTERED_IMAGE || ContentType == UNMODIFIED_PIXELS_IMAGE)
01564 {
01565
01566 CheckMandatoryEntry(0x0008,0x0016,"1.2.840.10008.5.1.4.1.1.7","UI");
01567 }
01568 else
01569 {
01570
01571
01572 CopyMandatoryEntry(0x0008,0x0016,"1.2.840.10008.5.1.4.1.1.7", "UI");
01573 }
01574
01575 Archive->Push(0x0028,0x005);
01576
01577 Archive->Push(0x0028,0x0015);
01578 Archive->Push(0x0028,0x0016);
01579 Archive->Push(0x0028,0x0017);
01580 Archive->Push(0x0028,0x0198);
01581 Archive->Push(0x0028,0x0199);
01582
01583
01584
01585
01587 DataEntry *e_0028_0012 = FileInternal->GetDataEntry(0x0028, 0x0012);
01588 if ( e_0028_0012 )
01589 {
01590 CopyMandatoryEntry(0x0028, 0x0008,e_0028_0012->GetString(),"IS");
01591 Archive->Push(0x0028,0x0012);
01592 }
01593
01594
01595
01596 if ( FileInternal->GetEntryString(0x0028,0x0100) == "12")
01597 {
01598 CopyMandatoryEntry(0x0028,0x0100,"16","US");
01599 }
01600
01601
01602
01603 std::ostringstream s;
01604
01605 int nbBitsAllocated = FileInternal->GetBitsAllocated();
01606 if ( (nbBitsAllocated == 0 || nbBitsAllocated > 32)
01607 || ( nbBitsAllocated > 8 && nbBitsAllocated <16) )
01608 {
01609 CopyMandatoryEntry(0x0028,0x0100,"16","US");
01610 gdcmWarningMacro("(0028,0100) changed from "
01611 << nbBitsAllocated << " to 16 for consistency purpose");
01612 nbBitsAllocated = 16;
01613 }
01614
01615 int nbBitsStored = FileInternal->GetBitsStored();
01616 if ( nbBitsStored == 0 || nbBitsStored > nbBitsAllocated )
01617 {
01618 s.str("");
01619 s << nbBitsAllocated;
01620 CopyMandatoryEntry(0x0028,0x0101,s.str(),"US");
01621 gdcmWarningMacro("(0028,0101) changed from "
01622 << nbBitsStored << " to " << nbBitsAllocated
01623 << " for consistency purpose" );
01624 nbBitsStored = nbBitsAllocated;
01625 }
01626
01627 int highBitPosition = FileInternal->GetHighBitPosition();
01628 if ( highBitPosition == 0 ||
01629 highBitPosition > nbBitsAllocated-1 ||
01630 highBitPosition < nbBitsStored-1 )
01631 {
01632 s.str("");
01633 s << nbBitsStored - 1;
01634 CopyMandatoryEntry(0x0028,0x0102,s.str(),"US");
01635 gdcmWarningMacro("(0028,0102) changed from "
01636 << highBitPosition << " to " << nbBitsAllocated-1
01637 << " for consistency purpose");
01638 }
01639
01640
01641
01642 DataEntry *e_0028_0103 = FileInternal->GetDataEntry(0x0028, 0x0103);
01643 if ( !e_0028_0103 )
01644 {
01645 gdcmWarningMacro("PixelRepresentation (0028,0103) is supposed to be mandatory");
01646 CopyMandatoryEntry(0x0028, 0x0103,"0","US");
01647 }
01648 else
01649 {
01650 int sign = (int)e_0028_0103->GetValue(0);
01651 if (sign !=1 && sign !=0)
01652 {
01653 gdcmWarningMacro("PixelRepresentation (0028,0103) is supposed to be =1 or =0");
01654 CopyMandatoryEntry(0x0028, 0x0103,"0","US");
01655 }
01656 }
01657
01658 std::string pixelSpacing = FileInternal->GetEntryString(0x0028,0x0030);
01659 if ( pixelSpacing == GDCM_UNFOUND )
01660 {
01661 pixelSpacing = "1.0\\1.0";
01662
01663 CopyMandatoryEntry(0x0028,0x0030,pixelSpacing,"DS");
01664 }
01665
01666
01667
01668 if ( ContentType != USER_OWN_IMAGE)
01669
01670
01671 CheckMandatoryEntry(0x0018,0x1164,pixelSpacing,"DS");
01672
01673
01675
01676
01677
01678
01679
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689
01690
01691
01692
01693
01694
01695
01696
01697
01698
01699
01700
01701
01702
01703
01704
01705
01706
01707
01708
01709
01710
01711
01712
01713
01714
01715
01716
01717
01718
01719
01720
01721 CheckMandatoryEntry(0x0028,0x0002,"1","US");
01722
01723
01724
01725
01726
01727
01728 CopyMandatoryEntry(0x0008,0x0018,sop,"UI");
01729
01730 if ( ContentType == USER_OWN_IMAGE)
01731 {
01732 gdcmDebugMacro( "USER_OWN_IMAGE (2)");
01733
01734
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746 CheckMandatoryEntry(0x0008,0x0064,"SYN","CS");
01747 }
01748
01749
01750
01752
01753
01754
01755
01756
01757
01758
01759
01760
01761
01762 const std::string &date = Util::GetCurrentDate();
01763 CopyMandatoryEntry(0x0008,0x0012,date,"DA");
01764
01765
01766 const std::string &time = Util::GetCurrentTime();
01767 CopyMandatoryEntry(0x0008,0x0013,time,"TM");
01768
01769
01770 CheckMandatoryEntry(0x0008,0x0020,date,"DA");
01771
01772 CheckMandatoryEntry(0x0008,0x0030,time,"TM");
01773
01774
01775
01776 CheckMandatoryEntry(0x0008,0x0050,"","SH");
01777
01778
01779
01780
01781
01782
01783
01784
01785
01786
01787
01788
01789
01790
01791
01792
01793
01794 CheckMandatoryEntry(0x0020,0x000d,Util::CreateUniqueUID(),"UI");
01795
01796
01797
01798
01799
01800
01801
01802 CheckMandatoryEntry(0x0020,0x000e,Util::CreateUniqueUID(),"UI");
01803
01804
01805 CheckMandatoryEntry(0x0020,0x0010,"","SH");
01806
01807
01808 CheckMandatoryEntry(0x0020,0x0011,"","IS");
01809
01810
01811 CheckMandatoryEntry(0x0020,0x0013,"","IS");
01812
01813
01814
01815 GDCM_NAME_SPACE::Orientation *o = GDCM_NAME_SPACE::Orientation::New();
01816 std::string ori = o->GetOrientation ( FileInternal );
01817 o->Delete();
01818 if (ori != "\\" && ori != GDCM_UNFOUND)
01819 CheckMandatoryEntry(0x0020,0x0020,ori,"CS");
01820 else
01821 CheckMandatoryEntry(0x0020,0x0020,"","CS");
01822
01823
01824 CheckMandatoryEntry(0x0018,0x5100,"HFS","CS");
01825
01826
01827 CheckMandatoryEntry(0x0008,0x0060,"OT","CS");
01828
01829
01830 CheckMandatoryEntry(0x0008,0x0070,"GDCM Factory","LO");
01831
01832
01833 CheckMandatoryEntry(0x0008,0x0080,"GDCM Hospital","LO");
01834
01835
01836 CheckMandatoryEntry(0x0010,0x0010,"GDCM^Patient","PN");
01837
01838
01839 CheckMandatoryEntry(0x0010,0x0020,"gdcm ID","LO");
01840
01841
01842 CheckMandatoryEntry(0x0010,0x0030,"","DA");
01843
01844
01845 CheckMandatoryEntry(0x0010,0x0040,"","CS");
01846
01847
01848 CheckMandatoryEntry(0x0008,0x0090,"","PN");
01849
01850
01851
01852
01853
01854
01855
01856
01857
01858
01859
01860
01861
01862
01863
01864
01865
01866
01867
01868
01869
01870 if (PhotometricInterpretation == 1)
01871 {
01872 }
01873 }
01874
01875 void FileHelper::CheckMandatoryEntry(uint16_t group,uint16_t elem,std::string value,const VRKey &vr )
01876 {
01877 DataEntry *entry = FileInternal->GetDataEntry(group,elem);
01878 if ( !entry )
01879 {
01880
01881 entry = DataEntry::New(group,elem,vr);
01882 entry->SetString(value);
01883 Archive->Push(entry);
01884 entry->Delete();
01885 }
01886 }
01887
01889 void FileHelper::SetMandatoryEntry(uint16_t group,uint16_t elem,std::string value,const VRKey &vr)
01890 {
01891
01892 DataEntry *entry = DataEntry::New(group,elem,vr);
01893 entry->SetString(value);
01894 Archive->Push(entry);
01895 entry->Delete();
01896 }
01897
01898 void FileHelper::CopyMandatoryEntry(uint16_t group,uint16_t elem,std::string value,const VRKey &vr)
01899 {
01900 DataEntry *entry = CopyDataEntry(group,elem,vr);
01901 entry->SetString(value);
01902 Archive->Push(entry);
01903 entry->Delete();
01904 }
01905
01909 void FileHelper::RestoreWriteMandatory()
01910 {
01911
01912 Archive->Restore(0x0002,0x0000);
01913 Archive->Restore(0x0002,0x0001);
01914 Archive->Restore(0x0002,0x0002);
01915 Archive->Restore(0x0002,0x0003);
01916 Archive->Restore(0x0002,0x0010);
01917 Archive->Restore(0x0002,0x0012);
01918 Archive->Restore(0x0002,0x0013);
01919 Archive->Restore(0x0002,0x0016);
01920 Archive->Restore(0x0002,0x0100);
01921 Archive->Restore(0x0002,0x0102);
01922
01923
01924
01925 Archive->Restore(0x0008,0x0012);
01926 Archive->Restore(0x0008,0x0013);
01927 Archive->Restore(0x0008,0x0016);
01928 Archive->Restore(0x0008,0x0018);
01929 Archive->Restore(0x0008,0x0060);
01930 Archive->Restore(0x0008,0x0070);
01931 Archive->Restore(0x0008,0x0080);
01932 Archive->Restore(0x0008,0x0090);
01933 Archive->Restore(0x0008,0x2112);
01934
01935 Archive->Restore(0x0010,0x0010);
01936 Archive->Restore(0x0010,0x0030);
01937 Archive->Restore(0x0010,0x0040);
01938
01939 Archive->Restore(0x0020,0x000d);
01940 Archive->Restore(0x0020,0x000e);
01941 }
01942
01946 void FileHelper::CallStartMethod()
01947 {
01948 Progress = 0.0f;
01949 Abort = false;
01950 CommandManager::ExecuteCommand(this,CMD_STARTPROGRESS);
01951 }
01952
01956 void FileHelper::CallProgressMethod()
01957 {
01958 CommandManager::ExecuteCommand(this,CMD_PROGRESS);
01959 }
01960
01964 void FileHelper::CallEndMethod()
01965 {
01966 Progress = 1.0f;
01967 CommandManager::ExecuteCommand(this,CMD_ENDPROGRESS);
01968 }
01969
01970
01971
01975 void FileHelper::Initialize()
01976 {
01977 UserFunction = 0;
01978 ContentType = USER_OWN_IMAGE;
01979
01980 WriteMode = WMODE_RAW;
01981 WriteType = ExplicitVR;
01982
01983 PhotometricInterpretation = 2;
01984
01985 PixelReadConverter = new PixelReadConvert;
01986 PixelWriteConverter = new PixelWriteConvert;
01987 Archive = new DocEntryArchive( FileInternal );
01988 }
01989
01996 uint8_t *FileHelper::GetRaw()
01997 {
01998 PixelReadConverter->SetUserFunction( UserFunction );
01999
02000 uint8_t *raw = PixelReadConverter->GetRaw();
02001 if ( ! raw )
02002 {
02003
02004 std::ifstream *fp = FileInternal->OpenFile();
02005 PixelReadConverter->ReadAndDecompressPixelData( fp );
02006 if ( fp )
02007 FileInternal->CloseFile();
02008
02009 raw = PixelReadConverter->GetRaw();
02010 if ( ! raw )
02011 {
02012 gdcmWarningMacro( "Read/decompress of pixel data apparently went wrong.");
02013 return 0;
02014 }
02015 }
02016 return raw;
02017 }
02018
02023 void FileHelper::ConvertFixGreyLevels(uint8_t *raw, size_t rawSize)
02024 {
02025 uint32_t i;
02026 int16_t j;
02027
02028
02029
02030 int bitsAllocated = FileInternal->GetBitsAllocated();
02031 if ( bitsAllocated == 0 )
02032 {
02033 bitsAllocated = 16;
02034 }
02035
02036 else if (bitsAllocated > 8 && bitsAllocated < 16 && bitsAllocated != 12)
02037 {
02038 bitsAllocated = 16;
02039 }
02040
02041
02042 int bitsStored = FileInternal->GetBitsStored();
02043 if ( bitsStored == 0 )
02044 {
02045 bitsStored = bitsAllocated;
02046 }
02047
02048 if (!FileInternal->IsSignedPixelData())
02049 {
02050 if ( bitsAllocated == 8 )
02051 {
02052 uint8_t *deb = (uint8_t *)raw;
02053 for (i=0; i<rawSize; i++)
02054 {
02055 *deb = 255 - *deb;
02056 deb++;
02057 }
02058 return;
02059 }
02060
02061 if ( bitsAllocated == 16 )
02062 {
02063 uint16_t mask =1;
02064 for (j=0; j<bitsStored-1; j++)
02065 {
02066 mask = (mask << 1) +1;
02067 }
02068
02069 uint16_t *deb = (uint16_t *)raw;
02070 for (i=0; i<rawSize/2; i++)
02071 {
02072 *deb = mask - *deb;
02073 deb++;
02074 }
02075 return;
02076 }
02077 }
02078 else
02079 {
02080 if ( bitsAllocated == 8 )
02081 {
02082 uint8_t smask8 = 255;
02083 uint8_t *deb = (uint8_t *)raw;
02084 for (i=0; i<rawSize; i++)
02085 {
02086 *deb = smask8 - *deb;
02087 deb++;
02088 }
02089 return;
02090 }
02091 if ( bitsAllocated == 16 )
02092 {
02093 uint16_t smask16 = 65535;
02094 uint16_t *deb = (uint16_t *)raw;
02095 for (i=0; i<rawSize/2; i++)
02096 {
02097 *deb = smask16 - *deb;
02098 deb++;
02099 }
02100 return;
02101 }
02102 }
02103 }
02104
02105
02111 void FileHelper::Print(std::ostream &os, std::string const &)
02112 {
02113 FileInternal->SetPrintLevel(PrintLevel);
02114 FileInternal->Print(os);
02115
02116 if ( FileInternal->IsReadable() )
02117 {
02118 PixelReadConverter->SetPrintLevel(PrintLevel);
02119 PixelReadConverter->Print(os);
02120 }
02121 }
02122
02123
02124 }
02125
02126
02127
02128
02129
02130
02131
02132
02133
02134
02135
02136
02137
02138
02139
02140
02141
02142
02143
02144
02145
02146
02147
02148
02149
02150
02151
02152
02153
02154
02155
02156
02157
02158
02159
02160
02161
02162
02163
02164
02165
02166
02167
02168
02169
02170
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182
02183
02184
02185
02186
02187
02188
02189
02190
02191
02192
02193
02194
02195
02196
02197
02198
02199
02200
02201
02202
02203
02204
02205
02206
02207
02208
02209
02210
02211
02212
02213
02214
02215
02216
02217
02218
02219
02220
02221
02222
02223
02224
02225
02226
02227
02228
02229
02230
02231
02232
02233
02234
02235
02236
02237
02238
02239
02240
02241
02242
02243
02244
02245
02246
02247
02248
02249
02250
02251
02252
02253
02254
02255
02256
02257
02258
02259
02260
02261
02262
02263
02264
02265
02266
02267
02268
02269
02270
02271
02272
02273
02274