00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "gdcmFileHelper.h"
00020 #include "gdcmGlobal.h"
00021 #include "gdcmTS.h"
00022 #include "gdcmDocument.h"
00023 #include "gdcmDebug.h"
00024 #include "gdcmUtil.h"
00025 #include "gdcmBinEntry.h"
00026 #include "gdcmValEntry.h"
00027 #include "gdcmContentEntry.h"
00028 #include "gdcmFile.h"
00029 #include "gdcmPixelReadConvert.h"
00030 #include "gdcmPixelWriteConvert.h"
00031 #include "gdcmDocEntryArchive.h"
00032
00033 #include <fstream>
00034
00035 namespace gdcm
00036 {
00037
00038
00051 FileHelper::FileHelper( )
00052 {
00053 FileInternal = new File( );
00054 SelfHeader = true;
00055 Initialize();
00056 }
00057
00071 FileHelper::FileHelper(File *header)
00072 {
00073 FileInternal = header;
00074 SelfHeader = false;
00075 Initialize();
00076 }
00077
00091 FileHelper::FileHelper(std::string const &filename )
00092 {
00093 FileInternal = new File( filename );
00094 SelfHeader = true;
00095 Initialize();
00096 }
00097
00103 FileHelper::~FileHelper()
00104 {
00105 if( PixelReadConverter )
00106 {
00107 delete PixelReadConverter;
00108 }
00109 if( PixelWriteConverter )
00110 {
00111 delete PixelWriteConverter;
00112 }
00113 if( Archive )
00114 {
00115 delete Archive;
00116 }
00117
00118 if( SelfHeader )
00119 {
00120 delete FileInternal;
00121 }
00122 FileInternal = 0;
00123 }
00124
00125
00126
00135 bool FileHelper::SetValEntry(std::string const &content,
00136 uint16_t group, uint16_t elem)
00137 {
00138 return FileInternal->SetValEntry(content,group,elem);
00139 }
00140
00141
00151 bool FileHelper::SetBinEntry(uint8_t *content, int lgth,
00152 uint16_t group, uint16_t elem)
00153 {
00154 return FileInternal->SetBinEntry(content,lgth,group,elem);
00155 }
00156
00166 ValEntry *FileHelper::InsertValEntry(std::string const &content,
00167 uint16_t group, uint16_t elem)
00168 {
00169 return FileInternal->InsertValEntry(content,group,elem);
00170 }
00171
00183 BinEntry *FileHelper::InsertBinEntry(uint8_t *binArea, int lgth,
00184 uint16_t group, uint16_t elem)
00185 {
00186 return FileInternal->InsertBinEntry(binArea,lgth,group,elem);
00187 }
00188
00198 SeqEntry *FileHelper::InsertSeqEntry(uint16_t group, uint16_t elem)
00199 {
00200 return FileInternal->InsertSeqEntry(group,elem);
00201 }
00202
00211 size_t FileHelper::GetImageDataSize()
00212 {
00213 if ( PixelWriteConverter->GetUserData() )
00214 {
00215 return PixelWriteConverter->GetUserDataSize();
00216 }
00217
00218 return PixelReadConverter->GetRGBSize();
00219 }
00220
00228 size_t FileHelper::GetImageDataRawSize()
00229 {
00230 if ( PixelWriteConverter->GetUserData() )
00231 {
00232 return PixelWriteConverter->GetUserDataSize();
00233 }
00234
00235 return PixelReadConverter->GetRawSize();
00236 }
00237
00248 uint8_t *FileHelper::GetImageData()
00249 {
00250 if ( PixelWriteConverter->GetUserData() )
00251 {
00252 return PixelWriteConverter->GetUserData();
00253 }
00254
00255 if ( ! GetRaw() )
00256 {
00257
00258 return 0;
00259 }
00260
00261 if ( FileInternal->HasLUT() && PixelReadConverter->BuildRGBImage() )
00262 {
00263 return PixelReadConverter->GetRGB();
00264 }
00265 else
00266 {
00267
00268 return PixelReadConverter->GetRaw();
00269 }
00270 }
00271
00281 uint8_t *FileHelper::GetImageDataRaw ()
00282 {
00283 return GetRaw();
00284 }
00285
00311 size_t FileHelper::GetImageDataIntoVector (void *destination, size_t maxSize)
00312 {
00313 if ( ! GetRaw() )
00314 {
00315
00316 return 0;
00317 }
00318
00319 if ( FileInternal->HasLUT() && PixelReadConverter->BuildRGBImage() )
00320 {
00321 if ( PixelReadConverter->GetRGBSize() > maxSize )
00322 {
00323 gdcmWarningMacro( "Pixel data bigger than caller's expected MaxSize");
00324 return 0;
00325 }
00326 memcpy( destination,
00327 (void*)PixelReadConverter->GetRGB(),
00328 PixelReadConverter->GetRGBSize() );
00329 return PixelReadConverter->GetRGBSize();
00330 }
00331
00332
00333 if ( PixelReadConverter->GetRawSize() > maxSize )
00334 {
00335 gdcmWarningMacro( "Pixel data bigger than caller's expected MaxSize");
00336 return 0;
00337 }
00338 memcpy( destination,
00339 (void*)PixelReadConverter->GetRaw(),
00340 PixelReadConverter->GetRawSize() );
00341 return PixelReadConverter->GetRawSize();
00342 }
00343
00359 void FileHelper::SetImageData(uint8_t *inData, size_t expectedSize)
00360 {
00361 SetUserData(inData,expectedSize);
00362 }
00363
00373 void FileHelper::SetUserData(uint8_t *inData, size_t expectedSize)
00374 {
00375 PixelWriteConverter->SetUserData(inData,expectedSize);
00376 }
00377
00382 uint8_t *FileHelper::GetUserData()
00383 {
00384 return PixelWriteConverter->GetUserData();
00385 }
00386
00391 size_t FileHelper::GetUserDataSize()
00392 {
00393 return PixelWriteConverter->GetUserDataSize();
00394 }
00395
00400 uint8_t *FileHelper::GetRGBData()
00401 {
00402 return PixelReadConverter->GetRGB();
00403 }
00404
00409 size_t FileHelper::GetRGBDataSize()
00410 {
00411 return PixelReadConverter->GetRGBSize();
00412 }
00413
00418 uint8_t *FileHelper::GetRawData()
00419 {
00420 return PixelReadConverter->GetRaw();
00421 }
00422
00427 size_t FileHelper::GetRawDataSize()
00428 {
00429 return PixelReadConverter->GetRawSize();
00430 }
00431
00435 uint8_t* FileHelper::GetLutRGBA()
00436 {
00437 return PixelReadConverter->GetLutRGBA();
00438 }
00439
00448 bool FileHelper::WriteRawData(std::string const &fileName)
00449 {
00450 std::ofstream fp1(fileName.c_str(), std::ios::out | std::ios::binary );
00451 if (!fp1)
00452 {
00453 gdcmWarningMacro( "Fail to open (write) file:" << fileName.c_str());
00454 return false;
00455 }
00456
00457 if( PixelWriteConverter->GetUserData() )
00458 {
00459 fp1.write( (char*)PixelWriteConverter->GetUserData(),
00460 PixelWriteConverter->GetUserDataSize() );
00461 }
00462 else if ( PixelReadConverter->GetRGB() )
00463 {
00464 fp1.write( (char*)PixelReadConverter->GetRGB(),
00465 PixelReadConverter->GetRGBSize());
00466 }
00467 else if ( PixelReadConverter->GetRaw() )
00468 {
00469 fp1.write( (char*)PixelReadConverter->GetRaw(),
00470 PixelReadConverter->GetRawSize());
00471 }
00472 else
00473 {
00474 gdcmErrorMacro( "Nothing written." );
00475 }
00476
00477 fp1.close();
00478
00479 return true;
00480 }
00481
00491 bool FileHelper::WriteDcmImplVR (std::string const &fileName)
00492 {
00493 SetWriteTypeToDcmImplVR();
00494 return Write(fileName);
00495 }
00496
00506 bool FileHelper::WriteDcmExplVR (std::string const &fileName)
00507 {
00508 SetWriteTypeToDcmExplVR();
00509 return Write(fileName);
00510 }
00511
00526 bool FileHelper::WriteAcr (std::string const &fileName)
00527 {
00528 SetWriteTypeToAcr();
00529 return Write(fileName);
00530 }
00531
00538 bool FileHelper::Write(std::string const &fileName)
00539 {
00540 switch(WriteType)
00541 {
00542 case ImplicitVR:
00543 SetWriteFileTypeToImplicitVR();
00544 break;
00545 case ExplicitVR:
00546 SetWriteFileTypeToExplicitVR();
00547 break;
00548 case ACR:
00549 case ACR_LIBIDO:
00550 SetWriteFileTypeToACR();
00551 break;
00552 default:
00553 SetWriteFileTypeToExplicitVR();
00554 }
00555
00556
00557
00558
00559
00560
00561
00564 if( WriteType == ACR_LIBIDO )
00565 {
00566 SetWriteToLibido();
00567 }
00568 else
00569 {
00570 SetWriteToNoLibido();
00571 }
00572
00573
00574 switch(WriteMode)
00575 {
00576 case WMODE_RAW :
00577 SetWriteToRaw();
00578 break;
00579 case WMODE_RGB :
00580 SetWriteToRGB();
00581 break;
00582 }
00583
00584 bool check = CheckWriteIntegrity();
00585 if(check)
00586 {
00587 check = FileInternal->Write(fileName,WriteType);
00588 }
00589
00590 RestoreWrite();
00591 RestoreWriteFileType();
00592
00593
00594
00595
00596
00597
00598 RestoreWriteOfLibido();
00599
00600
00601 return check;
00602 }
00603
00604
00605
00614 bool FileHelper::CheckWriteIntegrity()
00615 {
00616 if(PixelWriteConverter->GetUserData())
00617 {
00618 int numberBitsAllocated = FileInternal->GetBitsAllocated();
00619 if ( numberBitsAllocated == 0 || numberBitsAllocated == 12 )
00620 {
00621 numberBitsAllocated = 16;
00622 }
00623
00624 size_t decSize = FileInternal->GetXSize()
00625 * FileInternal->GetYSize()
00626 * FileInternal->GetZSize()
00627 * ( numberBitsAllocated / 8 )
00628 * FileInternal->GetSamplesPerPixel();
00629 size_t rgbSize = decSize;
00630 if( FileInternal->HasLUT() )
00631 rgbSize = decSize * 3;
00632
00633 switch(WriteMode)
00634 {
00635 case WMODE_RAW :
00636 if( decSize!=PixelWriteConverter->GetUserDataSize() )
00637 {
00638 gdcmWarningMacro( "Data size (Raw) is incorrect. Should be "
00639 << decSize << " / Found :"
00640 << PixelWriteConverter->GetUserDataSize() );
00641 return false;
00642 }
00643 break;
00644 case WMODE_RGB :
00645 if( rgbSize!=PixelWriteConverter->GetUserDataSize() )
00646 {
00647 gdcmWarningMacro( "Data size (RGB) is incorrect. Should be "
00648 << decSize << " / Found "
00649 << PixelWriteConverter->GetUserDataSize() );
00650 return false;
00651 }
00652 break;
00653 }
00654 }
00655
00656 return true;
00657 }
00658
00662 void FileHelper::SetWriteToRaw()
00663 {
00664 if( FileInternal->GetNumberOfScalarComponents() == 3
00665 && !FileInternal->HasLUT())
00666 {
00667 SetWriteToRGB();
00668 }
00669 else
00670 {
00671 ValEntry *photInt = CopyValEntry(0x0028,0x0004);
00672 if(FileInternal->HasLUT())
00673 {
00674 photInt->SetValue("PALETTE COLOR ");
00675 }
00676 else
00677 {
00678 photInt->SetValue("MONOCHROME1 ");
00679 }
00680
00681 PixelWriteConverter->SetReadData(PixelReadConverter->GetRaw(),
00682 PixelReadConverter->GetRawSize());
00683
00684 std::string vr = "OB";
00685 if( FileInternal->GetBitsAllocated()>8 )
00686 vr = "OW";
00687 if( FileInternal->GetBitsAllocated()==24 )
00688 vr = "OB";
00689 BinEntry *pixel =
00690 CopyBinEntry(GetFile()->GetGrPixel(),GetFile()->GetNumPixel(),vr);
00691 pixel->SetValue(GDCM_BINLOADED);
00692 pixel->SetBinArea(PixelWriteConverter->GetData(),false);
00693 pixel->SetLength(PixelWriteConverter->GetDataSize());
00694
00695 Archive->Push(photInt);
00696 Archive->Push(pixel);
00697 }
00698 }
00699
00703 void FileHelper::SetWriteToRGB()
00704 {
00705 if(FileInternal->GetNumberOfScalarComponents()==3)
00706 {
00707 PixelReadConverter->BuildRGBImage();
00708
00709 ValEntry *spp = CopyValEntry(0x0028,0x0002);
00710 spp->SetValue("3 ");
00711
00712 ValEntry *planConfig = CopyValEntry(0x0028,0x0006);
00713 planConfig->SetValue("0 ");
00714
00715 ValEntry *photInt = CopyValEntry(0x0028,0x0004);
00716 photInt->SetValue("RGB ");
00717
00718 if(PixelReadConverter->GetRGB())
00719 {
00720 PixelWriteConverter->SetReadData(PixelReadConverter->GetRGB(),
00721 PixelReadConverter->GetRGBSize());
00722 }
00723 else
00724 {
00725 PixelWriteConverter->SetReadData(PixelReadConverter->GetRaw(),
00726 PixelReadConverter->GetRawSize());
00727 }
00728
00729 std::string vr = "OB";
00730 if( FileInternal->GetBitsAllocated()>8 )
00731 vr = "OW";
00732 if( FileInternal->GetBitsAllocated()==24 )
00733 vr = "OB";
00734 BinEntry *pixel =
00735 CopyBinEntry(GetFile()->GetGrPixel(),GetFile()->GetNumPixel(),vr);
00736 pixel->SetValue(GDCM_BINLOADED);
00737 pixel->SetBinArea(PixelWriteConverter->GetData(),false);
00738 pixel->SetLength(PixelWriteConverter->GetDataSize());
00739
00740 Archive->Push(spp);
00741 Archive->Push(planConfig);
00742 Archive->Push(photInt);
00743 Archive->Push(pixel);
00744
00745
00746 Archive->Push(0x0028,0x1101);
00747 Archive->Push(0x0028,0x1102);
00748 Archive->Push(0x0028,0x1103);
00749 Archive->Push(0x0028,0x1201);
00750 Archive->Push(0x0028,0x1202);
00751 Archive->Push(0x0028,0x1203);
00752
00753
00754
00755
00756 if(FileInternal->GetBitsAllocated()==24)
00757 {
00758 ValEntry *bitsAlloc = CopyValEntry(0x0028,0x0100);
00759 bitsAlloc->SetValue("8 ");
00760
00761 ValEntry *bitsStored = CopyValEntry(0x0028,0x0101);
00762 bitsStored->SetValue("8 ");
00763
00764 ValEntry *highBit = CopyValEntry(0x0028,0x0102);
00765 highBit->SetValue("7 ");
00766
00767 Archive->Push(bitsAlloc);
00768 Archive->Push(bitsStored);
00769 Archive->Push(highBit);
00770 }
00771 }
00772 else
00773 {
00774 SetWriteToRaw();
00775 }
00776 }
00777
00781 void FileHelper::RestoreWrite()
00782 {
00783 Archive->Restore(0x0028,0x0002);
00784 Archive->Restore(0x0028,0x0004);
00785 Archive->Restore(0x0028,0x0006);
00786 Archive->Restore(GetFile()->GetGrPixel(),GetFile()->GetNumPixel());
00787
00788
00789 Archive->Restore(0x0028,0x0100);
00790 Archive->Restore(0x0028,0x0101);
00791 Archive->Restore(0x0028,0x0102);
00792
00793
00794 Archive->Restore(0x0028,0x1101);
00795 Archive->Restore(0x0028,0x1102);
00796 Archive->Restore(0x0028,0x1103);
00797 Archive->Restore(0x0028,0x1201);
00798 Archive->Restore(0x0028,0x1202);
00799 Archive->Restore(0x0028,0x1203);
00800 }
00801
00805 void FileHelper::SetWriteFileTypeToACR()
00806 {
00807 Archive->Push(0x0002,0x0010);
00808 }
00809
00813 void FileHelper::SetWriteFileTypeToExplicitVR()
00814 {
00815 std::string ts = Util::DicomString(
00816 Global::GetTS()->GetSpecialTransferSyntax(TS::ExplicitVRLittleEndian) );
00817
00818 ValEntry *tss = CopyValEntry(0x0002,0x0010);
00819 tss->SetValue(ts);
00820
00821 Archive->Push(tss);
00822 }
00823
00827 void FileHelper::SetWriteFileTypeToImplicitVR()
00828 {
00829 std::string ts = Util::DicomString(
00830 Global::GetTS()->GetSpecialTransferSyntax(TS::ImplicitVRLittleEndian) );
00831
00832 ValEntry *tss = CopyValEntry(0x0002,0x0010);
00833 tss->SetValue(ts);
00834
00835 Archive->Push(tss);
00836 }
00837
00838
00842 void FileHelper::RestoreWriteFileType()
00843 {
00844 Archive->Restore(0x0002,0x0010);
00845 }
00846
00850 void FileHelper::SetWriteToLibido()
00851 {
00852 ValEntry *oldRow = dynamic_cast<ValEntry *>
00853 (FileInternal->GetDocEntry(0x0028, 0x0010));
00854 ValEntry *oldCol = dynamic_cast<ValEntry *>
00855 (FileInternal->GetDocEntry(0x0028, 0x0011));
00856
00857 if( oldRow && oldCol )
00858 {
00859 std::string rows, columns;
00860
00861 ValEntry *newRow=new ValEntry(oldRow->GetDictEntry());
00862 ValEntry *newCol=new ValEntry(oldCol->GetDictEntry());
00863
00864 newRow->Copy(oldCol);
00865 newCol->Copy(oldRow);
00866
00867 newRow->SetValue(oldCol->GetValue());
00868 newCol->SetValue(oldRow->GetValue());
00869
00870 Archive->Push(newRow);
00871 Archive->Push(newCol);
00872 }
00873
00874 ValEntry *libidoCode = CopyValEntry(0x0008,0x0010);
00875 libidoCode->SetValue("ACRNEMA_LIBIDO_1.1");
00876 Archive->Push(libidoCode);
00877 }
00878
00882 void FileHelper::SetWriteToNoLibido()
00883 {
00884 ValEntry *recCode = dynamic_cast<ValEntry *>
00885 (FileInternal->GetDocEntry(0x0008,0x0010));
00886 if( recCode )
00887 {
00888 if( recCode->GetValue() == "ACRNEMA_LIBIDO_1.1" )
00889 {
00890 ValEntry *libidoCode = CopyValEntry(0x0008,0x0010);
00891 libidoCode->SetValue("");
00892 Archive->Push(libidoCode);
00893 }
00894 }
00895 }
00896
00900 void FileHelper::RestoreWriteOfLibido()
00901 {
00902 Archive->Restore(0x0028,0x0010);
00903 Archive->Restore(0x0028,0x0011);
00904 Archive->Restore(0x0008,0x0010);
00905 }
00906
00914 ValEntry *FileHelper::CopyValEntry(uint16_t group,uint16_t elem)
00915 {
00916 DocEntry *oldE = FileInternal->GetDocEntry(group, elem);
00917 ValEntry *newE;
00918
00919 if( oldE )
00920 {
00921 newE = new ValEntry(oldE->GetDictEntry());
00922 newE->Copy(oldE);
00923 }
00924 else
00925 {
00926 newE = GetFile()->NewValEntry(group,elem);
00927 }
00928
00929 return newE;
00930 }
00931
00941 BinEntry *FileHelper::CopyBinEntry(uint16_t group,uint16_t elem,
00942 const std::string &vr)
00943 {
00944 DocEntry *oldE = FileInternal->GetDocEntry(group, elem);
00945 BinEntry *newE;
00946
00947 if( oldE )
00948 if( oldE->GetVR()!=vr )
00949 oldE = NULL;
00950
00951 if( oldE )
00952 {
00953 newE = new BinEntry(oldE->GetDictEntry());
00954 newE->Copy(oldE);
00955 }
00956 else
00957 {
00958 newE = GetFile()->NewBinEntry(group,elem,vr);
00959 }
00960
00961 return newE;
00962 }
00963
00964
00965
00969 void FileHelper::Initialize()
00970 {
00971 WriteMode = WMODE_RAW;
00972 WriteType = ExplicitVR;
00973
00974 PixelReadConverter = new PixelReadConvert;
00975 PixelWriteConverter = new PixelWriteConvert;
00976 Archive = new DocEntryArchive( FileInternal );
00977
00978 if ( FileInternal->IsReadable() )
00979 {
00980 PixelReadConverter->GrabInformationsFromFile( FileInternal );
00981 }
00982 }
00983
00987 uint8_t *FileHelper::GetRaw()
00988 {
00989 uint8_t *raw = PixelReadConverter->GetRaw();
00990 if ( ! raw )
00991 {
00992
00993 std::ifstream *fp = FileInternal->OpenFile();
00994 PixelReadConverter->ReadAndDecompressPixelData( fp );
00995 if(fp)
00996 FileInternal->CloseFile();
00997
00998 raw = PixelReadConverter->GetRaw();
00999 if ( ! raw )
01000 {
01001 gdcmWarningMacro( "Read/decompress of pixel data apparently went wrong.");
01002 return 0;
01003 }
01004 }
01005
01006 return raw;
01007 }
01008
01009
01010
01011 void FileHelper::Print(std::ostream &os, std::string const &)
01012 {
01013 FileInternal->SetPrintLevel(PrintLevel);
01014 FileInternal->Print(os);
01015
01016 PixelReadConverter->SetPrintLevel(PrintLevel);
01017 PixelReadConverter->Print(os);
01018 }
01019
01020
01021 }