- vtkDebugMacro("Copying to memory image" << FileName.c_str());
- gdcmFile GdcmFile(FileName.c_str());
- size_t size = GdcmFile.GetImageDataSize();
-
- // 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 NumPlanes = GdcmFile.GetZSize();
- int LineSize = NumComponents * NumColumns * GdcmFile.GetPixelSize();
- unsigned char * Source = (unsigned char*)GdcmFile.GetImageData();
- unsigned char * pSource = Source; //pointer for later deletion
- unsigned char * Destination = Dest + size - LineSize;
-
- for (int plane = 0; plane < NumPlanes; plane++)
- {
- for (int line = 0; line < NumLines; line++)
+ // Get the image caracteristics
+ this->NumColumns = file->GetXSize();
+ this->NumLines = file->GetYSize();
+ this->NumPlanes = file->GetZSize();
+
+ 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();
+
+ // 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 )
+ {
+ // I could raise an error is AllowLookupTable is on and HasLUT() off
+ this->NumComponents = file->GetNumberOfScalarComponentsRaw();
+ }
+ else
+ {
+ this->NumComponents = file->GetNumberOfScalarComponents(); //rgb or mono
+ }
+}
+
+/*
+ * When more than one filename is specified (i.e. we expect loading
+ * a stack or volume) we need to check that the corresponding images/volumes
+ * to be loaded are coherent i.e. to make sure:
+ * - they all share the same X dimensions
+ * - they all share the same Y dimensions
+ * - they all share the same ImageType ( 8 bit signed, or unsigned...)
+ *
+ * Eventually, we emit a warning when all the files do NOT share the
+ * Z dimension, since we can still build a stack but the
+ * files are not coherent in Z, which is probably a source a trouble...
+ * When files are not readable (either the file cannot be opened or
+ * because gdcm cannot parse it), they are flagged as "GDCM_UNREADABLE".
+ * This method returns the total number of planar images to be loaded
+ * (i.e. an image represents one plane, but a volume represents many planes)
+ */
+/**
+ * Test the coherent informations of the file with the reference informations
+ * used as image caracteristics. The tested informations are :
+ * - they all share the same X dimensions
+ * - they all share the same Y dimensions
+ * - they all share the same Z dimensions
+ * - they all share the same number of components
+ * - they all share the same ImageType ( 8 bit signed, or unsigned...)
+ *
+ * \return True if the file match, False otherwise
+ */
+bool vtkGdcmReader::TestFileInformation(GDCM_NAME_SPACE::File *file)
+{
+ int numColumns = file->GetXSize();
+ int numLines = file->GetYSize();
+ int numPlanes = file->GetZSize();
+ int numComponents;
+ unsigned int pixelSize = file->GetPixelSize();
+
+ if( file->HasLUT() && this->AllowLookupTable )
+ numComponents = file->GetNumberOfScalarComponentsRaw();
+ else
+ numComponents = file->GetNumberOfScalarComponents(); //rgb or mono
+
+ if( numColumns != this->NumColumns )
+ {
+ vtkErrorMacro(<< "File X value doesn't match with the previous ones: "
+ << file->GetFileName().c_str()
+ << ". Found " << numColumns << ", must be "
+ << this->NumColumns);
+ return false;
+ }
+ if( numLines != this->NumLines )
+ {
+ vtkErrorMacro(<< "File Y value doesn't match with the previous ones: "
+ << file->GetFileName().c_str()
+ << ". Found " << numLines << ", must be "
+ << this->NumLines);
+ return false;
+ }
+ if( numPlanes != this->NumPlanes )
+ {
+ vtkErrorMacro(<< "File Z value doesn't match with the previous ones: "
+ << file->GetFileName().c_str()
+ << ". Found " << numPlanes << ", must be "
+ << this->NumPlanes);
+ return false;
+ }
+ if( numComponents != this->NumComponents )
+ {
+ vtkErrorMacro(<< "File Components count doesn't match with the previous ones: "
+ << file->GetFileName().c_str()
+ << ". Found " << numComponents << ", must be "
+ << this->NumComponents);
+ return false;
+ }
+ if( pixelSize != this->PixelSize )
+ {
+ vtkErrorMacro(<< "File pixel size doesn't match with the previous ones: "
+ << file->GetFileName().c_str()
+ << ". Found " << pixelSize << ", must be "
+ << this->PixelSize);
+ return false;
+ }
+
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// Private
+/*
+ * Remove all file names to the internal list of images to read.
+ */
+void vtkGdcmReader::RemoveAllInternalFileName(void)
+{
+ this->InternalFileNameList.clear();
+}
+
+/*
+ * Adds a file name to the internal list of images to read.
+ */
+void vtkGdcmReader::AddInternalFileName(const char *name)
+{
+ char *LocalName = new char[strlen(name) + 1];
+ strcpy(LocalName, name);
+ this->InternalFileNameList.push_back(LocalName);
+ delete[] LocalName;
+}
+
+/*
+ * Remove all file names to the internal list of images to read.
+ */
+void vtkGdcmReader::RemoveAllInternalFile(void)
+{
+ if(this->OwnFile)
+ {
+ for(gdcmFileList::iterator it=InternalFileList.begin();
+ it!=InternalFileList.end();
+ ++it)