]> Creatis software - gdcm.git/blobdiff - vtk/vtkGdcmReader.cxx
Add vtkGdcmReader::SetFlipY(bool) (default : true, to keep old behaviour)
[gdcm.git] / vtk / vtkGdcmReader.cxx
index cb2bb4b25cf19b7166474e0bf83eece58cf12639..91bc6b408223892c69e9df85c0e08e09c271f82f 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: vtkGdcmReader.cxx,v $
   Language:  C++
-  Date:      $Date: 2005/09/16 17:19:27 $
-  Version:   $Revision: 1.83 $
+  Date:      $Date: 2009/04/18 14:42:51 $
+  Version:   $Revision: 1.95 $
                                                                                 
   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.83 $")
+vtkCxxRevisionMacro(vtkGdcmReader, "$Revision: 1.95 $")
 vtkStandardNewMacro(vtkGdcmReader)
 
 //-----------------------------------------------------------------------------
@@ -78,16 +101,20 @@ 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 +183,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)
    {
@@ -266,13 +293,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 +328,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 +374,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 +384,7 @@ void vtkGdcmReader::BuildData(vtkDataObject *output)
          Dest += size;
       }
    }
+   this->RemoveAllInternalFile(); // For VTK5.0
 }
 
 /*
@@ -428,7 +468,7 @@ void vtkGdcmReader::BuildFileListFromPattern()
  */
 void vtkGdcmReader::LoadFileInformation()
 {
-   gdcm::File *file;
+   GDCM_NAME_SPACE::File *file;
    bool foundReference=false;
    std::string type;
 
@@ -452,7 +492,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 +503,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;
@@ -479,7 +519,7 @@ void vtkGdcmReader::LoadFileInformation()
                        << "   File type found : " << type.c_str() 
                        << " (might be 8U, 8S, 16U, 16S, 32U, 32S) \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,7 +574,7 @@ 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();
@@ -551,7 +591,22 @@ void vtkGdcmReader::GetFileInformation(gdcm::File *file)
 
    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 )
@@ -592,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();
@@ -681,7 +736,7 @@ void vtkGdcmReader::RemoveAllInternalFile(void)
                                  it!=InternalFileList.end();
                                  ++it)
       {
-         delete (*it);
+         (*it)->Delete();
       }
    }
    this->InternalFileList.clear();
@@ -696,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));
       }
    }
 }
@@ -713,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( );
@@ -726,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)
@@ -741,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();
@@ -755,7 +813,7 @@ void vtkGdcmReader::LoadImageInMemory(
       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:
@@ -793,15 +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(); 
       // useless - just an accessor;  'size' unused
-      src  = (unsigned char*)fileH->GetImageData();  
+      //if (this->GetFlipY())
+         src  = (unsigned char*)fileH->GetImageData();
+      //else
+      //   dest  = (unsigned char*)fileH->GetImageData();        
    } 
 
+
+if (this->GetFlipY()) {
    unsigned char *dst = dest + planeSize - lineSize;
    for (int plane = 0; plane < numPlanes; plane++)
    {
@@ -814,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
+{
+  memcpy((void*)dest, (void*)src,  numPlanes * numLines * lineSize);
+}
+   fileH->Delete();
 }
 
 //-----------------------------------------------------------------------------