X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=vtk%2FvtkGdcmReader.cxx;h=449eb536c67cb39824416ad4ac0e204ea8d8f6e0;hb=35ee8ee8af32946514713d271177df8bb2298eb2;hp=94a28226b79c43c2d65e1a10d8c2057c7b06ec84;hpb=d66701140e07d8e6fa7a529a8d2ae99d685026c5;p=gdcm.git diff --git a/vtk/vtkGdcmReader.cxx b/vtk/vtkGdcmReader.cxx index 94a28226..449eb536 100644 --- a/vtk/vtkGdcmReader.cxx +++ b/vtk/vtkGdcmReader.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: vtkGdcmReader.cxx,v $ Language: C++ - Date: $Date: 2005/08/30 15:25:25 $ - Version: $Revision: 1.79 $ + Date: $Date: 2011/03/29 07:36:02 $ + Version: $Revision: 1.99 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -20,14 +20,15 @@ // ////////////////////////////////////////////////////////////// // //===> Many users expect from vtkGdcmReader it 'orders' the images -// (that's the job of gdcm::SerieHelper ...) +// (that's the job of GDCM_NAME_SPACE::SerieHelper ...) // When user *knows* the files with same Serie UID // have same sizes, same 'pixel' type, same color convention, ... // the right way to proceed is as follow : // -// gdcm::SerieHelper *sh= new gdcm::SerieHelper(); +// GDCM_NAME_SPACE::SerieHelper *sh= new GDCM_NAME_SPACE::SerieHelper(); // // if user wants *not* to load some parts of the file headers // sh->SetLoadMode(loadMode); +// // // if user wants *not* to load some files // sh->AddRestriction(group, element, value, operator); // sh->AddRestriction( ... @@ -35,19 +36,40 @@ // // // if user wants to sort reverse order // sh->SetSortOrderToReverse(); -// // here, we suppose only the first Coherent File List is of interest -// gdcm::FileList *l = sh->GetFirstCoherentFileList(); +// +// // here, we suppose only the first 'Serie' is of interest +// // it's up to the user to decide ! +// GDCM_NAME_SPACE::FileList *l = sh->GetFirstSingleSerieUIDFileSet(); +// // // if user is doesn't trust too much the files with same Serie UID // if ( !sh->IsCoherent(l) ) // return; // not same sizes, same 'pixel' type -> stop +// +// // WARNING : all that follows works only with 'bona fide' Series +// // (In some Series; there are more than one 'orientation' +// // Don't expected to build a 'volume' with that! +// // +// // -> use sh->SplitOnOrientation(l) +// // - or sh->SplitOnPosition(l), or SplitOnTagValue(l, gr, el) - +// // depending on what you want to do +// // and iterate on the various 'X Coherent File Sets' +// +// // if user *knows* he has to drop the 'duplicates' images +// // (same Position) +// sh->SetDropDuplicatePositions(true); +// +// // Sorting the list is mandatory +// // a side effect is to compute ZSpacing for the file set // sh->OrderFileList(l); // sort the list // // vtkGdcmReader *reader = vtkGdcmReader::New(); +// // // if user wants to modify pixel order (Mirror, TopDown, 90°Rotate, ...) // // he has to supply the function that does the job // // (a *very* simple example is given in vtkgdcmSerieViewer.cxx) // reader->SetUserFunction (userSuppliedFunction); -// // to pass a 'Coherent File List' as produced by gdcm::SerieHelper +// +// // to pass a 'Coherent File List' as produced by GDCM_NAME_SPACE::SerieHelper // reader->SetCoherentFileList(l); // reader->Update(); // @@ -59,6 +81,7 @@ #include "gdcmFileHelper.h" #include "gdcmFile.h" +#include "gdcmSerieHelper.h" // for ImagePositionPatientOrdering() #include "vtkGdcmReader.h" #include "gdcmDebug.h" @@ -69,7 +92,7 @@ #include #include -vtkCxxRevisionMacro(vtkGdcmReader, "$Revision: 1.79 $") +vtkCxxRevisionMacro(vtkGdcmReader, "$Revision: 1.99 $") vtkStandardNewMacro(vtkGdcmReader) //----------------------------------------------------------------------------- @@ -78,16 +101,19 @@ vtkGdcmReader::vtkGdcmReader() { this->LookupTable = NULL; this->AllowLookupTable = false; - this->AllowLightChecking = false; - this->LoadMode = gdcm::LD_ALL; // Load everything (possible values : - // - LD_NOSEQ, - // - LD_NOSHADOW, - // - LD_NOSHADOWSEQ) + //this->AllowLightChecking = false; + this->LoadMode = GDCM_NAME_SPACE::LD_ALL; // Load everything (possible values : + // - LD_NOSEQ, + // - LD_NOSHADOW, + // - LD_NOSHADOWSEQ) this->CoherentFileList = 0; this->UserFunction = 0; this->OwnFile=true; - this->Execution=false; + // this->Execution=false; // For VTK5.0 + + this->KeepOverlays = false; + this->FlipY = true; // to keep old behaviour } vtkGdcmReader::~vtkGdcmReader() @@ -156,10 +182,10 @@ void vtkGdcmReader::SetFileName(const char *name) */ void vtkGdcmReader::ExecuteInformation() { - if(this->Execution) - return; - - this->Execution=true; +// if(this->Execution) // For VTK5.0 +// return; +// +// this->Execution=true; // end For VTK5.0 this->RemoveAllInternalFile(); if(this->MTime>this->fileTime) { @@ -255,7 +281,7 @@ void vtkGdcmReader::ExecuteInformation() vtkDebugMacro(<< "32 bits signed image"); this->SetDataScalarTypeToInt(); } - else if ( ImageType == "FD" ) + else if ( ImageType == "FD" ) // This is not genuine DICOM, but so usefull { vtkDebugMacro(<< "64 bits Double image"); this->SetDataScalarTypeToDouble(); @@ -266,13 +292,13 @@ void vtkGdcmReader::ExecuteInformation() this->fileTime=this->MTime; } - this->Superclass::ExecuteInformation(); + this->Superclass::ExecuteInformation(); - this->GetOutput()->SetUpdateExtentToWholeExtent(); - this->BuildData(this->GetOutput()); + //this->GetOutput()->SetUpdateExtentToWholeExtent();// For VTK5.0 + //this->BuildData(this->GetOutput()); - this->Execution=false; - this->RemoveAllInternalFile(); + //this->Execution=false; + //this->RemoveAllInternalFile(); // End For VTK5.0 } /* @@ -301,11 +327,23 @@ void vtkGdcmReader::ExecuteData(vtkDataObject *output) return; } */ -} - -void vtkGdcmReader::BuildData(vtkDataObject *output) -{ - vtkImageData *data = this->AllocateOutputData(output); + + // data->AllocateScalars(); // For VTK5.0 + // if (this->UpdateExtentIsEmpty(output)) + // { + // return; + // } +//} // end For VTK5.0 + + data->AllocateScalars(); // For VTK5.0 + +#if (VTK_MAJOR_VERSION >= 5) || ( VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 2 ) +//#if (VTK_MAJOR_VERSION >= 5) + if (this->UpdateExtentIsEmpty(output)) + { + return; + } +#endif data->GetPointData()->GetScalars()->SetName("DicomImage-Volume"); @@ -335,7 +373,7 @@ void vtkGdcmReader::BuildData(vtkDataObject *output) size_t size = this->NumColumns * this->NumLines * this->NumPlanes * data->GetScalarSize() * this->NumComponents; unsigned char *Dest = (unsigned char *)data->GetScalarPointer(); - for (std::vector::iterator it = InternalFileList.begin(); + for (std::vector::iterator it = InternalFileList.begin(); it != InternalFileList.end(); ++it) { @@ -345,6 +383,7 @@ void vtkGdcmReader::BuildData(vtkDataObject *output) Dest += size; } } + this->RemoveAllInternalFile(); // For VTK5.0 } /* @@ -428,7 +467,7 @@ void vtkGdcmReader::BuildFileListFromPattern() */ void vtkGdcmReader::LoadFileInformation() { - gdcm::File *file; + GDCM_NAME_SPACE::File *file; bool foundReference=false; std::string type; @@ -452,7 +491,7 @@ void vtkGdcmReader::LoadFileInformation() fclose(fp); // Read the file - file=new gdcm::File(); + file=GDCM_NAME_SPACE::File::New(); file->SetLoadMode( LoadMode ); file->SetFileName(filename->c_str() ); file->Load(); @@ -463,7 +502,7 @@ void vtkGdcmReader::LoadFileInformation() vtkErrorMacro(<< "Gdcm cannot parse file " << filename->c_str()); vtkErrorMacro(<< "Removing this file from read files: " << filename->c_str()); - delete file; + file->Delete(); file=NULL; InternalFileList.push_back(file); continue; @@ -473,13 +512,14 @@ void vtkGdcmReader::LoadFileInformation() type = file->GetPixelType(); if ( (type != "8U") && (type != "8S") && (type != "16U") && (type != "16S") - && (type != "32U") && (type != "32S") ) + && (type != "32U") && (type != "32S") + && (type != "FD") ) // Sure this one is NOT kosher { vtkErrorMacro(<< "Bad File Type for file " << filename->c_str() << "\n" << " File type found : " << type.c_str() - << " (might be 8U, 8S, 16U, 16S, 32U, 32S) \n" + << " (might be 8U, 8S, 16U, 16S, 32U, 32S, FD) \n" << " Removing this file from read files"); - delete file; + file->Delete(); file=NULL; InternalFileList.push_back(file); continue; @@ -499,7 +539,7 @@ void vtkGdcmReader::LoadFileInformation() } else if(!TestFileInformation(file)) { - delete file; + file->Delete(); file=NULL; } @@ -534,20 +574,39 @@ void vtkGdcmReader::UpdateFileInformation() * These informations are required to specify the output image * caracteristics */ -void vtkGdcmReader::GetFileInformation(gdcm::File *file) +void vtkGdcmReader::GetFileInformation(GDCM_NAME_SPACE::File *file) { // Get the image caracteristics this->NumColumns = file->GetXSize(); this->NumLines = file->GetYSize(); this->NumPlanes = file->GetZSize(); - this->TotalNumberOfPlanes = this->NumPlanes*InternalFileNameList.size(); + + if (CoherentFileList == 0) + this->TotalNumberOfPlanes = this->NumPlanes*InternalFileNameList.size(); + else + this->TotalNumberOfPlanes = this->NumPlanes*CoherentFileList->size(); this->ImageType = file->GetPixelType(); this->PixelSize = file->GetPixelSize(); this->DataSpacing[0] = file->GetXSpacing(); this->DataSpacing[1] = file->GetYSpacing(); - this->DataSpacing[2] = file->GetZSpacing(); + + // Most of the file headers have NO z spacing + // It must be calculated from the whole GDCM_NAME_SPACE::Serie (if any) + // using Jolinda Smith's algoritm. + // see GDCM_NAME_SPACE::SerieHelper::ImagePositionPatientOrdering() + if (CoherentFileList == 0) + this->DataSpacing[2] = file->GetZSpacing(); + else + { + // Just because OrderFileList() is a member of GDCM_NAME_SPACE::SerieHelper + // we need to instanciate sh. + GDCM_NAME_SPACE::SerieHelper *sh = GDCM_NAME_SPACE::SerieHelper::New(); + sh->OrderFileList(CoherentFileList); // calls ImagePositionPatientOrdering() + this->DataSpacing[2] = sh->GetZSpacing(); + sh->Delete(); + } // Get the image data caracteristics if( file->HasLUT() && this->AllowLookupTable ) @@ -588,7 +647,7 @@ void vtkGdcmReader::GetFileInformation(gdcm::File *file) * * \return True if the file match, False otherwise */ -bool vtkGdcmReader::TestFileInformation(gdcm::File *file) +bool vtkGdcmReader::TestFileInformation(GDCM_NAME_SPACE::File *file) { int numColumns = file->GetXSize(); int numLines = file->GetYSize(); @@ -611,7 +670,7 @@ bool vtkGdcmReader::TestFileInformation(gdcm::File *file) } if( numLines != this->NumLines ) { - vtkErrorMacro(<< "File y value doesn't match with the previous ones: " + vtkErrorMacro(<< "File Y value doesn't match with the previous ones: " << file->GetFileName().c_str() << ". Found " << numLines << ", must be " << this->NumLines); @@ -619,7 +678,7 @@ bool vtkGdcmReader::TestFileInformation(gdcm::File *file) } if( numPlanes != this->NumPlanes ) { - vtkErrorMacro(<< "File z value doesn't match with the previous ones: " + vtkErrorMacro(<< "File Z value doesn't match with the previous ones: " << file->GetFileName().c_str() << ". Found " << numPlanes << ", must be " << this->NumPlanes); @@ -677,7 +736,7 @@ void vtkGdcmReader::RemoveAllInternalFile(void) it!=InternalFileList.end(); ++it) { - delete (*it); + (*it)->Delete(); } } this->InternalFileList.clear(); @@ -692,7 +751,8 @@ void vtkGdcmReader::IncrementProgress(const unsigned long updateProgressTarget, { if (!(updateProgressCount%updateProgressTarget)) { - this->UpdateProgress(updateProgressCount/(50.0*updateProgressTarget)); + this->UpdateProgress( + updateProgressCount/(50.0*updateProgressTarget)); } } } @@ -709,8 +769,8 @@ void vtkGdcmReader::IncrementProgress(const unsigned long updateProgressTarget, { vtkDebugMacro(<< "Copying to memory image [" << fileName.c_str() << "]"); - gdcm::File *f; - f = new gdcm::File(); + GDCM_NAME_SPACE::File *f; + f = new GDCM_NAME_SPACE::File(); f->SetLoadMode( LoadMode ); f->SetFileName( fileName.c_str() ); f->Load( ); @@ -722,14 +782,14 @@ void vtkGdcmReader::IncrementProgress(const unsigned long updateProgressTarget, }*/ /* - * Loads the contents of the image/volume contained by gdcm::File* f at + * Loads the contents of the image/volume contained by GDCM_NAME_SPACE::File* f at * the Dest memory address. Returns the size of the data loaded. * \ param f File to consider. NULL if the file must be skiped * \remarks Assume that if (f != NULL) then its caracteristics match * with the previous ones */ void vtkGdcmReader::LoadImageInMemory( - gdcm::File *f, + GDCM_NAME_SPACE::File *f, unsigned char *dest, const unsigned long updateProgressTarget, unsigned long &updateProgressCount) @@ -737,9 +797,11 @@ void vtkGdcmReader::LoadImageInMemory( if(!f) return; - gdcm::FileHelper *fileH = new gdcm::FileHelper( f ); + GDCM_NAME_SPACE::FileHelper *fileH = GDCM_NAME_SPACE::FileHelper::New( f ); fileH->SetUserFunction( UserFunction ); - + + fileH->SetKeepOverlays ( this->KeepOverlays); + int numColumns = f->GetXSize(); int numLines = f->GetYSize(); int numPlanes = f->GetZSize(); @@ -749,9 +811,9 @@ void vtkGdcmReader::LoadImageInMemory( numComponents = f->GetNumberOfScalarComponentsRaw(); else numComponents = f->GetNumberOfScalarComponents(); //rgb or mono - + vtkDebugMacro(<< "numComponents:" << numComponents); vtkDebugMacro(<< "Copying to memory image [" << f->GetFileName().c_str() << "]"); - size_t size; + //size_t size; // If the data structure of vtk for image/volume representation // were straigthforwards the following would be enough: @@ -767,7 +829,8 @@ void vtkGdcmReader::LoadImageInMemory( if( fileH->GetFile()->HasLUT() && AllowLookupTable ) { - size = fileH->GetImageDataSize(); + // to avoid bcc 5.5 w + /*size = */ fileH->GetImageDataSize(); src = (unsigned char*) fileH->GetImageDataRaw(); unsigned char *lut = (unsigned char*) fileH->GetLutRGBA(); @@ -788,14 +851,20 @@ void vtkGdcmReader::LoadImageInMemory( this->LookupTable->SetRange(0,255); vtkDataSetAttributes *a = this->GetOutput()->GetPointData(); a->GetScalars()->SetLookupTable(this->LookupTable); - free(lut); + delete[] lut; } else { - size = fileH->GetImageDataSize(); - src = (unsigned char*)fileH->GetImageData(); - } + //size = fileH->GetImageDataSize(); + // useless - just an accessor; 'size' unused + //if (this->GetFlipY()) + src = (unsigned char*)fileH->GetImageData(); + //else + // very strange, but it doesn't work (I have to memcpy the pixels ?!?) + // dest = (unsigned char*)fileH->GetImageData(); + } +if (this->GetFlipY()) { unsigned char *dst = dest + planeSize - lineSize; for (int plane = 0; plane < numPlanes; plane++) { @@ -808,14 +877,19 @@ void vtkGdcmReader::LoadImageInMemory( // Update progress related: if (!(updateProgressCount%updateProgressTarget)) { - this->UpdateProgress(updateProgressCount/(50.0*updateProgressTarget)); + this->UpdateProgress( + updateProgressCount/(50.0*updateProgressTarget)); } updateProgressCount++; } dst += 2 * planeSize; } - - delete fileH; +} +else // we don't flip (upside down) the image +{ + memcpy((void*)dest, (void*)src, numPlanes * numLines * lineSize); +} + fileH->Delete(); } //-----------------------------------------------------------------------------