]> Creatis software - gdcm.git/commitdiff
* vtk/vtkGdcmReader[cxx|h] should now be volume aware (read ready for
authorfrog <frog>
Fri, 30 May 2003 18:48:35 +0000 (18:48 +0000)
committerfrog <frog>
Fri, 30 May 2003 18:48:35 +0000 (18:48 +0000)
        debug stage).
      * gdcmPython/demo/vtkGdcmReader.py: commented lines for volume test

ChangeLog
gdcmPython/demo/vtkGdcmReader.py
vtk/vtkGdcmReader.cxx
vtk/vtkGdcmReader.h

index 8030bc988a8bb999ec3f016320ca55030700fd85..a1ba8651d4b5a826c4a34d5c4b1d51c68399e307 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2003-05-30  Eric Boix <Eric.Boix@creatis.insa-lyon.fr>
+      * vtk/vtkGdcmReader[cxx|h] should now be volume aware (read ready for
+        debug stage).
+      * gdcmPython/demo/vtkGdcmReader.py: commented lines for volume test
+
 2003-05-29  Eric Boix <Eric.Boix@creatis.insa-lyon.fr>
       * vtk/vtkGdcmReader[cxx|h] preparation addons for loading volumes.
 
index e93b1927861dc167922a7fecfddc10664423946a..eb68e14dd239c7747a9b16c52251b5fd8ef95938 100644 (file)
@@ -22,6 +22,9 @@ if not test.IsReadable():
 del test
 toDisplay = vtkGdcmReader()
 toDisplay.SetFileName(FileName)
+### Uncomment to test for volumes:
+###toDisplay.DebugOn()
+###toDisplay.AddFileName(FileName)
 toDisplay.UpdateWholeExtent()
 
 VTKtable = vtkLookupTable()
index b9324dcbbeea3127e26b85daf9ea9c06233fdb9a..7c1d8c0339465ed6fcc74279221b07593c98f859 100644 (file)
@@ -1,4 +1,4 @@
-// $Header: /cvs/public/gdcm/vtk/vtkGdcmReader.cxx,v 1.6 2003/05/29 16:58:24 frog Exp $
+// $Header: /cvs/public/gdcm/vtk/vtkGdcmReader.cxx,v 1.7 2003/05/30 18:48:36 frog Exp $
 //CLEANME#include <vtkByteSwap.h>
 #include <stdio.h>
 #include <vtkObjectFactory.h>
@@ -30,6 +30,7 @@ void vtkGdcmReader::AddFileName(const char* name)
    // Starting from two files we have a stack of images:
    if(this->FileNameList.size() >= 2)
       this->SetFileDimensionality(3);
+  this->Modified();
 }
 
 //----------------------------------------------------------------------------
@@ -151,7 +152,7 @@ bool vtkGdcmReader::CheckFileCoherence()
          ReferenceNY = NY;
          ReferenceNZ = NZ;
          ReferenceType = type;
-         vtkDebugMacro("File is taken a coherence references" << *FileName);
+         vtkDebugMacro("This file taken as coherence reference:" << *FileName);
        }
      } // End of loop on FileName
 
@@ -182,26 +183,13 @@ void vtkGdcmReader::ExecuteInformation()
     this->DataExtent[4] = this->DataVOI[4];
     this->DataExtent[5] = this->DataVOI[5];
     }
-
-  this->ComputeInternalFileName(this->DataExtent[4]);
-  
-  // Check for file existence.
-  FILE *fp;
-  fp = fopen(this->InternalFileName,"rb");
-  if (!fp)
-    {
-    vtkErrorMacro("Unable to open file " << this->InternalFileName);
-    return;
-    }
-  fclose(fp);
-
-  // Check for Gdcm parsability
-  gdcmHeader GdcmHeader(this->InternalFileName);
-  if (!GdcmHeader.IsReadable())
+  if ( ! this->CheckFileCoherence() )
     {
-    vtkErrorMacro("Gdcm cannot parse file " << this->InternalFileName);
-    return;
+       vtkErrorMacro("File set is not coherent. Exiting...");
+       return;
     }
+  string ReferenceFile = this->FileNameList.front();
+  gdcmHeader GdcmHeader(ReferenceFile.c_str());
 
   int NX = GdcmHeader.GetXSize();
   int NY = GdcmHeader.GetYSize();
@@ -224,7 +212,7 @@ void vtkGdcmReader::ExecuteInformation()
         (this->DataVOI[5] >= NZ))
       {
       vtkWarningMacro("The requested VOI is larger than the file's ("
-                      << this->InternalFileName << ") extent ");
+                      << ReferenceFile << ") extent ");
       this->DataVOI[0] = 0;
       this->DataVOI[1] = NX - 1;
       this->DataVOI[2] = 0;
@@ -284,7 +272,7 @@ void vtkGdcmReader::ExecuteInformation()
     }
   else
     {
-    vtkErrorMacro("Bad File Type " << this->InternalFileName
+    vtkErrorMacro("Bad File Type " << ReferenceFile
                                    << "Type " << type.c_str());
     return;
     }
@@ -292,6 +280,45 @@ void vtkGdcmReader::ExecuteInformation()
   vtkImageReader::ExecuteInformation();
 }
 
+//----------------------------------------------------------------------------
+void vtkGdcmReader::LoadImageInMemory(string FileName, 
+                                      unsigned char * Dest,
+                                      size_t size)
+{
+  vtkDebugMacro("Copying to memmory image" << FileName.c_str());
+  gdcmFile GdcmFile(FileName.c_str());
+
+  if (GdcmFile.GetZSize() != 1 )
+    vtkErrorMacro("Cannot handle images with multiple planes");
+
+  // First check the expected size of the image is the one found by gdcm.
+  if ( size != GdcmFile.GetImageDataSize() )
+    {
+    vtkErrorMacro("Inconsistency with GetImageDataSize for file" 
+                  << FileName.c_str());
+    vtkErrorMacro("Number of scalar components"
+                  << this->NumberOfScalarComponents);
+    }
+
+  // If the data structure of vtk for image/volume representation
+  // were straigthforwards the following would suffice:
+  //    GdcmFile.GetImageDataIntoVector((void*)Dest, size);
+  // But vtk chose to invert the lines of an image, that is the last
+  // line comes first (for some axis related reasons?). Hence we need
+  // to load the image line by line, starting from the end:
+  int NumColumns = GdcmFile.GetXSize();
+  int NumLines   = GdcmFile.GetYSize();
+  int LineSize   = NumColumns * GdcmFile.GetPixelSize();
+  unsigned char * Source      = (unsigned char*)GdcmFile.GetImageData();
+  unsigned char * Destination = Dest + size - LineSize;
+  for (int i = 0; i < NumLines; i++)
+    {
+    memcpy((void*)Destination, (void*)Source, LineSize);
+    Source      += LineSize;
+    Destination -= LineSize;
+    }
+}
+
 //----------------------------------------------------------------------------
 // Update -> UpdateData -> Execute -> ExecuteData (see vtkSource.cxx for
 // last step.
@@ -301,19 +328,21 @@ void vtkGdcmReader::ExecuteInformation()
 // same as the file extent/order.
 void vtkGdcmReader::ExecuteData(vtkDataObject *output)
 {
-  if (!this->FileName)
+  if (this->FileNameList.empty())
     {
-    vtkErrorMacro("A valid FileName must be specified.");
+    vtkErrorMacro("A least a valid FileName must be specified.");
     return;
     }
 
   vtkImageData *data = this->AllocateOutputData(output);
   data->SetExtent(this->DataExtent);
-  data->GetPointData()->GetScalars()->SetName("ImageFile");
+  data->GetPointData()->GetScalars()->SetName("DicomImage-Volume");
 
   // First check the coherence between the DataExtent and the
-  // size of the pixel data as annouced by gdcm (looks a bit paranoid).
-  gdcmFile GdcmFile(this->InternalFileName);
+  // size of the pixel data as annouced by gdcm (looks a bit paranoid)
+  // for the reference file (i.e. the first one in the list):
+  string ReferenceFile = this->FileNameList.front();
+  gdcmFile GdcmFile(ReferenceFile.c_str());
   int NumColumns = this->DataExtent[1] - this->DataExtent[0] + 1;
   int NumLines   = this->DataExtent[3] - this->DataExtent[2] + 1;
   int NumPlanes  = this->DataExtent[5] - this->DataExtent[4] + 1;
@@ -324,28 +353,27 @@ void vtkGdcmReader::ExecuteData(vtkDataObject *output)
     vtkDebugMacro("Number of scalar components"
                   << this->NumberOfScalarComponents);
     }
+
+  // The memory size for a full stack of images of course depends
+  // on the number of images:
+  size_t stack_size = size * this->FileNameList.size();
   // Allocate pixel data space itself.
-  unsigned char *mem = new unsigned char [size];
+  unsigned char *mem = new unsigned char [stack_size];
 
-  // If the data structure of vtk for image/volume representation
-  // were straigthforwards the following would suffice:
-  //    GdcmFile.GetImageDataIntoVector((void*)mem, size);
-  // But vtk chose to invert the lines of an image, that is the last
-  // line comes first (for some axis related reasons?). Hence we need
-  // to load the image line by line, starting from the end:
-  int LineSize = NumColumns * GdcmFile.GetPixelSize();
-  unsigned char * Source      = (unsigned char*)GdcmFile.GetImageData();
-  unsigned char * Destination = mem + size - LineSize;
-  for (int i = 0; i < NumLines; i++)
+  unsigned char * Dest = mem;
+  for (std::list<std::string>::iterator FileName  = FileNameList.begin();
+                                        FileName != FileNameList.end();
+                                      ++FileName)
     {
-    memcpy((void*)Destination, (void*)Source, LineSize);
-    Source      += LineSize;
-    Destination -= LineSize;
+       this->LoadImageInMemory(*FileName, Dest, size);
+       Dest += size;
     }
+
+
   // The "size" of the vtkScalars data is expressed in number of points,
   // and is not the memory size representing those points:
-  size = size / GdcmFile.GetPixelSize();
-  data->GetPointData()->GetScalars()->SetVoidArray(mem, size, 0);
+  stack_size = stack_size / GdcmFile.GetPixelSize();
+  data->GetPointData()->GetScalars()->SetVoidArray(mem, stack_size, 0);
   this->Modified();
 
 }
index dbcd0faeb24314f4551f4908402897f4e98c3bb8..418e69b992a09a2920ab79fe38c5ea14cdce39a1 100644 (file)
@@ -1,4 +1,4 @@
-// $Header: /cvs/public/gdcm/vtk/vtkGdcmReader.h,v 1.2 2003/05/29 16:58:24 frog Exp $
+// $Header: /cvs/public/gdcm/vtk/vtkGdcmReader.h,v 1.3 2003/05/30 18:48:36 frog Exp $
 
 #ifndef __vtkGdcmReader_h
 #define __vtkGdcmReader_h
@@ -22,10 +22,12 @@ protected:
   void ExecuteData(vtkDataObject *output);
   void BuilFileListFromPattern();
   bool CheckFileCoherence();
+private:
   // List of filenames to be read in order to build a stack of images
   // or volume. The order in the list shall be the order of the images.
   //BTX
   std::list<std::string> FileNameList;
+  void LoadImageInMemory(string FileName, unsigned char * Dest, size_t size);
   //ETX
 };
 #endif