]> Creatis software - gdcm.git/blobdiff - vtk/vtkGdcmReader.cxx
minor re-indent
[gdcm.git] / vtk / vtkGdcmReader.cxx
index 51597358c097dcee5ff34b7bf24c16ad0c3ba973..913f9a7417c29c0110f6a39ca8e119f30d5cd71e 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: vtkGdcmReader.cxx,v $
   Language:  C++
-  Date:      $Date: 2005/08/30 14:40:35 $
-  Version:   $Revision: 1.77 $
+  Date:      $Date: 2010/09/01 13:33:36 $
+  Version:   $Revision: 1.98 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
 // //////////////////////////////////////////////////////////////
 //
 //===>  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( ...
 //
 //      // 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 <vtkPointData.h>
 #include <vtkLookupTable.h>
 
-vtkCxxRevisionMacro(vtkGdcmReader, "$Revision: 1.77 $")
+vtkCxxRevisionMacro(vtkGdcmReader, "$Revision: 1.98 $")
 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<gdcm::File* >::iterator it =  InternalFileList.begin();
+      for (std::vector<GDCM_NAME_SPACE::File* >::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,13 +647,13 @@ 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();
    int numPlanes  = file->GetZSize();
-   int pixelSize  = file->GetPixelSize();
    int numComponents;
+   unsigned int pixelSize  = file->GetPixelSize();
 
    if( file->HasLUT() && this->AllowLookupTable )
       numComponents = file->GetNumberOfScalarComponentsRaw();
@@ -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();
 }
 
 //-----------------------------------------------------------------------------