X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=src%2FgdcmFile.cxx;h=03df5b7046dfe768f8ac42b1ffe9679f31856c51;hb=1c35ba5e5bc72b0861b92698dd4ea29f0bab5f73;hp=ca361e54cf377fe0fc2f589b3566581d6e9b2b90;hpb=af698856153f426a4d852b6645e238f669d42276;p=gdcm.git diff --git a/src/gdcmFile.cxx b/src/gdcmFile.cxx index ca361e54..03df5b70 100644 --- a/src/gdcmFile.cxx +++ b/src/gdcmFile.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmFile.cxx,v $ Language: C++ - Date: $Date: 2004/11/26 10:55:04 $ - Version: $Revision: 1.166 $ + Date: $Date: 2004/12/07 17:28:50 $ + Version: $Revision: 1.174 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -21,6 +21,11 @@ #include "gdcmDebug.h" #include "gdcmUtil.h" #include "gdcmBinEntry.h" +#include "gdcmHeader.h" +#include "gdcmPixelReadConvert.h" +#include "gdcmPixelWriteConvert.h" +#include "gdcmDocEntryArchive.h" + #include namespace gdcm @@ -29,6 +34,26 @@ typedef std::pair IterHT; //------------------------------------------------------------------------- // Constructor / Destructor +/** + * \brief Constructor dedicated to deal with the *pixels* area of a ACR/DICOMV3 + * file (Header only deals with the ... header) + * Opens (in read only and when possible) an existing file and checks + * for DICOM compliance. Returns NULL on failure. + * It will be up to the user to load the pixels into memory + * (see GetImageData, GetImageDataRaw) + * \note the in-memory representation of all available tags found in + * the DICOM header is post-poned to first header information access. + * This avoid a double parsing of public part of the header when + * one sets an a posteriori shadow dictionary (efficiency can be + * seen as a side effect). + */ +File::File( ) +{ + HeaderInternal = new Header( ); + SelfHeader = true; + Initialise(); +} + /** * \brief Constructor dedicated to deal with the *pixels* area of a ACR/DICOMV3 * file (Header only deals with the ... header) @@ -77,18 +102,16 @@ File::File(std::string const & filename ) void File::Initialise() { WriteMode = WMODE_DECOMPRESSED; - WriteType = WTYPE_IMPL_VR; + WriteType = ExplicitVR; - PixelConverter = new PixelConvert; + PixelReadConverter = new PixelReadConvert; + PixelWriteConverter = new PixelWriteConvert; Archive = new DocEntryArchive( HeaderInternal ); if ( HeaderInternal->IsReadable() ) { - PixelConverter->GrabInformationsFromHeader( HeaderInternal ); + PixelReadConverter->GrabInformationsFromHeader( HeaderInternal ); } - - Pixel_Data = 0; - ImageDataSize = 0; } /** @@ -98,9 +121,13 @@ void File::Initialise() */ File::~File() { - if( PixelConverter ) + if( PixelReadConverter ) { - delete PixelConverter; + delete PixelReadConverter; + } + if( PixelWriteConverter ) + { + delete PixelWriteConverter; } if( Archive ) { @@ -128,7 +155,7 @@ File::~File() */ size_t File::GetImageDataSize() { - return PixelConverter->GetRGBSize(); + return PixelReadConverter->GetRGBSize(); } /** @@ -140,7 +167,7 @@ size_t File::GetImageDataSize() */ size_t File::GetImageDataRawSize() { - return PixelConverter->GetDecompressedSize(); + return PixelReadConverter->GetDecompressedSize(); } /** @@ -161,14 +188,14 @@ uint8_t* File::GetImageData() return 0; } - if ( HeaderInternal->HasLUT() && PixelConverter->BuildRGBImage() ) + if ( HeaderInternal->HasLUT() && PixelReadConverter->BuildRGBImage() ) { - return PixelConverter->GetRGB(); + return PixelReadConverter->GetRGB(); } else { // When no LUT or LUT conversion fails, return the decompressed - return PixelConverter->GetDecompressed(); + return PixelReadConverter->GetDecompressed(); } } @@ -205,31 +232,31 @@ size_t File::GetImageDataIntoVector (void* destination, size_t maxSize) return 0; } - if ( HeaderInternal->HasLUT() && PixelConverter->BuildRGBImage() ) + if ( HeaderInternal->HasLUT() && PixelReadConverter->BuildRGBImage() ) { - if ( PixelConverter->GetRGBSize() > maxSize ) + if ( PixelReadConverter->GetRGBSize() > maxSize ) { dbg.Verbose(0, "File::GetImageDataIntoVector: pixel data bigger" "than caller's expected MaxSize"); return 0; } memcpy( destination, - (void*)PixelConverter->GetRGB(), - PixelConverter->GetRGBSize() ); - return PixelConverter->GetRGBSize(); + (void*)PixelReadConverter->GetRGB(), + PixelReadConverter->GetRGBSize() ); + return PixelReadConverter->GetRGBSize(); } // Either no LUT conversion necessary or LUT conversion failed - if ( PixelConverter->GetDecompressedSize() > maxSize ) + if ( PixelReadConverter->GetDecompressedSize() > maxSize ) { dbg.Verbose(0, "File::GetImageDataIntoVector: pixel data bigger" "than caller's expected MaxSize"); return 0; } memcpy( destination, - (void*)PixelConverter->GetDecompressed(), - PixelConverter->GetDecompressedSize() ); - return PixelConverter->GetDecompressedSize(); + (void*)PixelReadConverter->GetDecompressed(), + PixelReadConverter->GetDecompressedSize() ); + return PixelReadConverter->GetDecompressedSize(); } /** @@ -248,16 +275,16 @@ uint8_t* File::GetImageDataRaw () uint8_t* File::GetDecompressed() { - uint8_t* decompressed = PixelConverter->GetDecompressed(); + uint8_t* decompressed = PixelReadConverter->GetDecompressed(); if ( ! decompressed ) { // The decompressed image migth not be loaded yet: std::ifstream* fp = HeaderInternal->OpenFile(); - PixelConverter->ReadAndDecompressPixelData( fp ); + PixelReadConverter->ReadAndDecompressPixelData( fp ); if(fp) HeaderInternal->CloseFile(); - decompressed = PixelConverter->GetDecompressed(); + decompressed = PixelReadConverter->GetDecompressed(); if ( ! decompressed ) { dbg.Verbose(0, "File::GetDecompressed: read/decompress of " @@ -270,7 +297,7 @@ uint8_t* File::GetDecompressed() } /** - * \brief Points the internal Pixel_Data pointer to the callers inData + * \brief Points the internal pointer to the callers inData * image representation, BUT WITHOUT COPYING THE DATA. * 'image' Pixels are presented as C-like 2D arrays : line per line. * 'volume'Pixels are presented as C-like 3D arrays : plane per plane @@ -284,10 +311,8 @@ uint8_t* File::GetDecompressed() */ bool File::SetImageData(uint8_t* inData, size_t expectedSize) { -// FIXME : if already allocated, memory leak ! - Pixel_Data = inData; - ImageDataSize = expectedSize; -// FIXME : 7fe0, 0010 IS NOT set ... + PixelWriteConverter->SetUserData(inData,expectedSize); + return true; } @@ -308,7 +333,14 @@ bool File::WriteRawData(std::string const & fileName) dbg.Verbose(2, "Fail to open (write) file:", fileName.c_str()); return false; } - fp1.write((char*)Pixel_Data, ImageDataSize); + + if(PixelWriteConverter->GetUserData()) + fp1.write((char*)PixelWriteConverter->GetUserData(), PixelWriteConverter->GetUserDataSize()); + else if(PixelReadConverter->GetRGB()) + fp1.write((char*)PixelReadConverter->GetRGB(), PixelReadConverter->GetRGBSize()); + else if(PixelReadConverter->GetDecompressed()) + fp1.write((char*)PixelReadConverter->GetDecompressed(), PixelReadConverter->GetDecompressedSize()); + fp1.close(); return true; @@ -365,24 +397,33 @@ bool File::WriteAcr (std::string const & fileName) bool File::Write(std::string const& fileName) { - switch(WriteType) - { - case WTYPE_IMPL_VR: - return WriteBase(fileName,ImplicitVR); - case WTYPE_EXPL_VR: - return WriteBase(fileName,ExplicitVR); - case WTYPE_ACR: - return WriteBase(fileName,ACR); - } - return(false); + return WriteBase(fileName); +} + +bool File::SetEntryByNumber(std::string const& content, + uint16_t group, uint16_t element) +{ + return HeaderInternal->SetEntryByNumber(content,group,element); +} + +bool File::SetEntryByNumber(uint8_t* content, int lgth, + uint16_t group, uint16_t element) +{ + return HeaderInternal->SetEntryByNumber(content,lgth,group,element); +} + +bool File::ReplaceOrCreateByNumber(std::string const& content, + uint16_t group, uint16_t element) +{ + return HeaderInternal->ReplaceOrCreateByNumber(content,group,element) != NULL; } /** - * \brief Access to the underlying \ref PixelConverter RGBA LUT + * \brief Access to the underlying \ref PixelReadConverter RGBA LUT */ uint8_t* File::GetLutRGBA() { - return PixelConverter->GetLutRGBA(); + return PixelReadConverter->GetLutRGBA(); } //----------------------------------------------------------------------------- @@ -395,9 +436,9 @@ uint8_t* File::GetLutRGBA() * @param type file type (ExplicitVR, ImplicitVR, ...) * @return false if write fails */ -bool File::WriteBase (std::string const & fileName, FileType type) +bool File::WriteBase (std::string const & fileName) { - switch(type) + switch(WriteType) { case ImplicitVR: SetWriteFileTypeToImplicitVR(); @@ -406,27 +447,12 @@ bool File::WriteBase (std::string const & fileName, FileType type) SetWriteFileTypeToExplicitVR(); break; case ACR: - SetWriteFileTypeToACR(); - break; case ACR_LIBIDO: - SetWriteFileTypeToACRLibido(); + SetWriteFileTypeToACR(); break; default: SetWriteFileTypeToExplicitVR(); } - - switch(WriteMode) - { - case WMODE_NATIVE : - SetWriteToNative(); - break; - case WMODE_DECOMPRESSED : - SetWriteToDecompressed(); - break; - case WMODE_RGB : - SetWriteToRGB(); - break; - } // -------------------------------------------------------------- // Special Patch to allow gdcm to re-write ACR-LibIDO formated images @@ -436,32 +462,43 @@ bool File::WriteBase (std::string const & fileName, FileType type) // just before writting ... /// \todo the best trick would be *change* the recognition code /// but pb expected if user deals with, e.g. COMPLEX images -/* if ( HeaderInternal->GetFileType() == ACR_LIBIDO) + if( WriteType == ACR_LIBIDO ) { SetWriteToLibido(); - }*/ + } + else + { + SetWriteToNoLibido(); + } // ----------------- End of Special Patch ---------------- + + switch(WriteMode) + { + case WMODE_DECOMPRESSED : + SetWriteToDecompressed(); + break; + case WMODE_RGB : + SetWriteToRGB(); + break; + } bool check = CheckWriteIntegrity(); if(check) { - check = HeaderInternal->Write(fileName,type); + check = HeaderInternal->Write(fileName,WriteType); } + RestoreWrite(); + RestoreWriteFileType(); + // -------------------------------------------------------------- // Special Patch to allow gdcm to re-write ACR-LibIDO formated images // // ...and we restore the Header to be Dicom Compliant again // just after writting -/* if ( HeaderInternal->GetFileType() == ACR_LIBIDO ) - { - RestoreWriteFromLibido(); - }*/ + RestoreWriteOfLibido(); // ----------------- End of Special Patch ---------------- - RestoreWrite(); - RestoreWriteFileType(); - return check; } @@ -475,7 +512,7 @@ bool File::WriteBase (std::string const & fileName, FileType type) */ bool File::CheckWriteIntegrity() { - if(Pixel_Data) + if(PixelWriteConverter->GetUserData()) { int numberBitsAllocated = HeaderInternal->GetBitsAllocated(); if ( numberBitsAllocated == 0 || numberBitsAllocated == 12 ) @@ -494,21 +531,17 @@ bool File::CheckWriteIntegrity() switch(WriteMode) { - case WMODE_NATIVE : - break; case WMODE_DECOMPRESSED : - if( decSize!=ImageDataSize ) + if( decSize!=PixelWriteConverter->GetUserDataSize() ) { dbg.Verbose(0, "File::CheckWriteIntegrity: Data size is incorrect"); - //std::cerr<<"Dec : "<GetUserDataSize() ) { dbg.Verbose(0, "File::CheckWriteIntegrity: Data size is incorrect"); - //std::cerr<<"RGB : "<GetGrPixel(),GetHeader()->GetNumPixel()); - pixel->SetValue(GDCM_BINLOADED); - pixel->SetBinArea(Pixel_Data,false); - pixel->SetLength(ImageDataSize); - - Archive->Push(pixel); - } -} - void File::SetWriteToDecompressed() { if(HeaderInternal->GetNumberOfScalarComponents()==3 && !HeaderInternal->HasLUT()) @@ -543,26 +563,19 @@ void File::SetWriteToDecompressed() if(HeaderInternal->HasLUT()) { photInt->SetValue("PALETTE COLOR "); - photInt->SetLength(14); } else { photInt->SetValue("MONOCHROME1 "); - photInt->SetLength(12); } + PixelWriteConverter->SetReadData(PixelReadConverter->GetDecompressed(), + PixelReadConverter->GetDecompressedSize()); + BinEntry* pixel = CopyBinEntry(GetHeader()->GetGrPixel(),GetHeader()->GetNumPixel()); pixel->SetValue(GDCM_BINLOADED); - if(Pixel_Data) - { - pixel->SetBinArea(Pixel_Data,false); - pixel->SetLength(ImageDataSize); - } - else - { - pixel->SetBinArea(PixelConverter->GetDecompressed(),false); - pixel->SetLength(PixelConverter->GetDecompressedSize()); - } + pixel->SetBinArea(PixelWriteConverter->GetData(),false); + pixel->SetLength(PixelWriteConverter->GetDataSize()); Archive->Push(photInt); Archive->Push(pixel); @@ -573,38 +586,33 @@ void File::SetWriteToRGB() { if(HeaderInternal->GetNumberOfScalarComponents()==3) { - PixelConverter->BuildRGBImage(); + PixelReadConverter->BuildRGBImage(); ValEntry* spp = CopyValEntry(0x0028,0x0002); spp->SetValue("3 "); - spp->SetLength(2); ValEntry* planConfig = CopyValEntry(0x0028,0x0006); planConfig->SetValue("0 "); - planConfig->SetLength(2); ValEntry* photInt = CopyValEntry(0x0028,0x0004); photInt->SetValue("RGB "); - photInt->SetLength(4); - BinEntry* pixel = CopyBinEntry(GetHeader()->GetGrPixel(),GetHeader()->GetNumPixel()); - pixel->SetValue(GDCM_BINLOADED); - if(Pixel_Data) + if(PixelReadConverter->GetRGB()) { - pixel->SetBinArea(Pixel_Data,false); - pixel->SetLength(ImageDataSize); - } - else if(PixelConverter->GetRGB()) - { - pixel->SetBinArea(PixelConverter->GetRGB(),false); - pixel->SetLength(PixelConverter->GetRGBSize()); + PixelWriteConverter->SetReadData(PixelReadConverter->GetRGB(), + PixelReadConverter->GetRGBSize()); } else // Decompressed data { - pixel->SetBinArea(PixelConverter->GetDecompressed(),false); - pixel->SetLength(PixelConverter->GetDecompressedSize()); + PixelWriteConverter->SetReadData(PixelReadConverter->GetDecompressed(), + PixelReadConverter->GetDecompressedSize()); } + BinEntry* pixel = CopyBinEntry(GetHeader()->GetGrPixel(),GetHeader()->GetNumPixel()); + pixel->SetValue(GDCM_BINLOADED); + pixel->SetBinArea(PixelWriteConverter->GetData(),false); + pixel->SetLength(PixelWriteConverter->GetDataSize()); + Archive->Push(spp); Archive->Push(planConfig); Archive->Push(photInt); @@ -625,15 +633,12 @@ void File::SetWriteToRGB() { ValEntry* bitsAlloc = CopyValEntry(0x0028,0x0100); bitsAlloc->SetValue("8 "); - bitsAlloc->SetLength(2); ValEntry* bitsStored = CopyValEntry(0x0028,0x0101); bitsStored->SetValue("8 "); - bitsStored->SetLength(2); ValEntry* highBit = CopyValEntry(0x0028,0x0102); highBit->SetValue("7 "); - highBit->SetLength(2); Archive->Push(bitsAlloc); Archive->Push(bitsStored); @@ -672,11 +677,6 @@ void File::SetWriteFileTypeToACR() Archive->Push(0x0002,0x0010); } -void File::SetWriteFileTypeToACRLibido() -{ - SetWriteFileTypeToACR(); -} - void File::SetWriteFileTypeToExplicitVR() { std::string ts = Util::DicomString( @@ -684,7 +684,6 @@ void File::SetWriteFileTypeToExplicitVR() ValEntry* tss = CopyValEntry(0x0002,0x0010); tss->SetValue(ts); - tss->SetLength(ts.length()); Archive->Push(tss); } @@ -696,7 +695,6 @@ void File::SetWriteFileTypeToImplicitVR() ValEntry* tss = CopyValEntry(0x0002,0x0010); tss->SetValue(ts); - tss->SetLength(ts.length()); } void File::RestoreWriteFileType() @@ -725,12 +723,31 @@ void File::SetWriteToLibido() Archive->Push(newRow); Archive->Push(newCol); } + + ValEntry *libidoCode = CopyValEntry(0x0008,0x0010); + libidoCode->SetValue("ACRNEMA_LIBIDO_1.1"); + Archive->Push(libidoCode); } -void File::RestoreWriteFromLibido() +void File::SetWriteToNoLibido() +{ + ValEntry *recCode = dynamic_cast(HeaderInternal->GetDocEntryByNumber(0x0008,0x0010)); + if( recCode ) + { + if( recCode->GetValue() == "ACRNEMA_LIBIDO_1.1" ) + { + ValEntry *libidoCode = CopyValEntry(0x0008,0x0010); + libidoCode->SetValue(""); + Archive->Push(libidoCode); + } + } +} + +void File::RestoreWriteOfLibido() { Archive->Restore(0x0028,0x0010); Archive->Restore(0x0028,0x0011); + Archive->Restore(0x0008,0x0010); } ValEntry* File::CopyValEntry(uint16_t group,uint16_t element) @@ -766,7 +783,6 @@ BinEntry* File::CopyBinEntry(uint16_t group,uint16_t element) newE = GetHeader()->NewBinEntryByNumber(group,element); } - return(newE); }