+ vtkDebugMacro(<< "Copying to memory image [" << fileName.c_str() << "]");
+
+ gdcm::File *f;
+ f = new gdcm::File();
+ f->SetLoadMode( LoadMode );
+ f->SetFileName( fileName.c_str() );
+ f->Load( );
+
+ return DoTheLoadingJob (f,
+ dest,
+ updateProgressTarget,
+ updateProgressCount);
+ delete f;
+}
+
+/*
+ * Service method for LoadImageInMemory
+*/
+size_t vtkGdcmReader::DoTheLoadingJob (gdcm::File *f,
+ unsigned char *dest,
+ const unsigned long updateProgressTarget,
+ unsigned long &updateProgressCount)
+{
+ gdcm::FileHelper *fileH = new gdcm::FileHelper( f );
+ fileH->SetUserFunction( UserFunction );
+
+ size_t size;
+
+ // If the data structure of vtk for image/volume representation
+ // were straigthforwards the following would be enough:
+ // GdcmFile.GetImageDataIntoVector((void*)Dest, size);
+ // But vtk chooses 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 = fileH->GetFile()->GetXSize();
+ int numLines = fileH->GetFile()->GetYSize();
+ int numPlanes = fileH->GetFile()->GetZSize();
+ int lineSize = NumComponents * numColumns * fileH->GetFile()->GetPixelSize();
+ int planeSize = lineSize * numLines;
+
+ unsigned char *src;
+
+ if( fileH->GetFile()->HasLUT() && AllowLookupTable )
+ {
+ size = fileH->GetImageDataSize();
+ src = (unsigned char*) fileH->GetImageDataRaw();
+ unsigned char *lut = (unsigned char*) fileH->GetLutRGBA();
+
+ if(!this->LookupTable)
+ {
+ this->LookupTable = vtkLookupTable::New();
+ }
+
+ this->LookupTable->SetNumberOfTableValues(256);
+ for (int tmp=0; tmp<256; tmp++)
+ {
+ this->LookupTable->SetTableValue(tmp,
+ (float)lut[4*tmp+0]/255.0,
+ (float)lut[4*tmp+1]/255.0,
+ (float)lut[4*tmp+2]/255.0,
+ 1);
+ }
+ this->LookupTable->SetRange(0,255);
+ vtkDataSetAttributes *a = this->GetOutput()->GetPointData();
+ a->GetScalars()->SetLookupTable(this->LookupTable);
+ free(lut);
+ }
+ else
+ {
+ size = fileH->GetImageDataSize();
+ src = (unsigned char*)fileH->GetImageData();
+ }
+
+ unsigned char *dst = dest + planeSize - lineSize;
+ for (int plane = 0; plane < numPlanes; plane++)
+ {
+ for (int line = 0; line < numLines; line++)
+ {
+ // Copy one line at proper destination:
+ memcpy((void*)dst, (void*)src, lineSize);
+ src += lineSize;
+ dst -= lineSize;
+ // Update progress related:
+ if (!(updateProgressCount%updateProgressTarget))
+ {
+ this->UpdateProgress(updateProgressCount/(50.0*updateProgressTarget));
+ }
+ updateProgressCount++;
+ }
+ dst += 2 * planeSize;
+ }
+ delete fileH;
+ return size;
+}
+
+// -------------------------------------------------------------------------
+
+// We assume the use *does* know all the files whose names
+// are in InternalFileNameList exist, may be open, are gdcm-readable
+// have the same sizes, have the same 'pixel' type, are single frame
+// have the same color convention, ..., anything else ?
+
+int vtkGdcmReader::CheckFileCoherenceLight()
+{
+ std::list<std::string>::iterator filename = InternalFileNameList.begin();
+
+ gdcm::File GdcmFile;
+ GdcmFile.SetLoadMode( LoadMode );
+ GdcmFile.SetFileName(filename->c_str() );
+ GdcmFile.Load( );
+
+ if (!GdcmFile.IsReadable())
+ {
+ vtkErrorMacro(<< "Gdcm cannot parse file " << filename->c_str());
+ vtkErrorMacro(<< "you should try vtkGdcmReader::CheckFileCoherence "
+ << "instead of vtkGdcmReader::CheckFileCoherenceLight");
+ return 0;
+ }
+ int NX = GdcmFile.GetXSize();
+ int NY = GdcmFile.GetYSize();
+ // CheckFileCoherenceLight should be called *only* when user knows
+ // he deals with single frames files.
+ // Z size is then the number of files.
+ int NZ = InternalFileNameList.size();
+ std::string type = GdcmFile.GetPixelType();
+ vtkDebugMacro(<< "The first file is taken as reference: "
+ << filename->c_str());
+ vtkDebugMacro(<< "Image dimensions of reference file as read from Gdcm:"
+ << NX << " " << NY << " " << NZ);
+ vtkDebugMacro(<< "Number of planes added to the stack: " << NZ);
+ // Set aside the size of the image
+ this->NumColumns = NX;
+ this->NumLines = NY;
+ this->ImageType = type;
+ this->PixelSize = GdcmFile.GetPixelSize();
+
+ if( GdcmFile.HasLUT() && this->AllowLookupTable )
+ {
+ // I could raise an error is AllowLookupTable is on and HasLUT() off
+ this->NumComponents = GdcmFile.GetNumberOfScalarComponentsRaw();
+ }
+ else
+ {
+ this->NumComponents = GdcmFile.GetNumberOfScalarComponents(); //rgb or mono
+ }
+
+ //Set image spacing
+ this->DataSpacing[0] = GdcmFile.GetXSpacing();
+ this->DataSpacing[1] = GdcmFile.GetYSpacing();
+ this->DataSpacing[2] = GdcmFile.GetZSpacing();
+
+ return InternalFileNameList.size();
+}
+
+// We assume the use *does* know all the files whose names
+// are in InternalFileNameList exist, may be open, are gdcm-readable
+// have the same sizes, have the same 'pixel' type, are single frame
+// have the same color convention, ..., anything else ?
+
+int vtkGdcmReader::CheckFileCoherenceAlreadyDone()
+{
+ if ( CoherentFileList->empty() )
+ {
+ vtkErrorMacro(<< "Coherent File List is empty ");
+ return 0;
+ }
+
+ gdcm::File *gdcmFile = (*CoherentFileList)[0];
+
+ int NX = gdcmFile->GetXSize();
+ int NY = gdcmFile->GetYSize();
+ // CheckFileCoherenceLight should be called *only* when user knows
+ // he deals with single frames files.
+ // Z size is then the number of files.
+ // --> TODO : loop on the File* to get NZ of each one !
+ int NZ = CoherentFileList->size();
+ std::string type = gdcmFile->GetPixelType();
+ //vtkDebugMacro(<< "The first file is taken as reference: "
+ // << (*CoherentFileList)[0]->GetFileName() );
+ vtkDebugMacro(<< "Image dimensions of reference file as read from Gdcm:"
+ << NX << " " << NY << " " << NZ);
+ vtkDebugMacro(<< "Number of planes added to the stack: " << NZ);
+ // Set aside the size of the image
+ this->NumColumns = NX;
+ this->NumLines = NY;
+ this->ImageType = type;
+ this->PixelSize = gdcmFile->GetPixelSize();
+
+ if( gdcmFile->HasLUT() && this->AllowLookupTable )
+ {
+ // I could raise an error is AllowLookupTable is on and HasLUT() off
+ this->NumComponents = gdcmFile->GetNumberOfScalarComponentsRaw();
+ }
+ else
+ {
+ this->NumComponents = gdcmFile->GetNumberOfScalarComponents(); //rgb or mono
+ }
+
+ //Set image spacing
+ this->DataSpacing[0] = gdcmFile->GetXSpacing();
+ this->DataSpacing[1] = gdcmFile->GetYSpacing();
+ this->DataSpacing[2] = gdcmFile->GetZSpacing();
+
+ return NZ;