vtkImageImport with CopyImportVoidPointer does not offer 'save' option
For vtk 8.2: I want to import pixel-data into a vtkImageData object, but find issues with the pixels buffer being freed prematurely. This code finds the pixel data to be freed prematurely.
vtkImageImport *vtkImport = vtkImageImport::New();
vtkImport->SetWholeExtent(0, src.Size(MX4::Dim1) - 1, 0, src.Size(MX4::Dim2) - 1, 0, src.Size(MX4::Dim3) - 1);
int maxx = src.Size(MX4::Dim1)-1;
int maxy = src.Size(MX4::Dim2)-1;
int maxz = src.Size(MX4::Dim3)-1;
vtkImport->SetDataExtentToWholeExtent();
vtkImport->SetDataScalarTypeToShort();
vtkImport->SetNumberOfScalarComponents(1);
int vTotalSize = src.Size(MX4::Dim1) * src.Size(MX4::Dim2) * src.Size(MX4::Dim3);
// Allocate the pixel buffer for vtk to own.
short *vImageBufferForVtk = new short[vTotalSize];
short *srcPixel = src.Data();
for (int i = 0;i < vTotalSize;i++)
{
vImageBufferForVtk[i] = *srcPixel++;
}
vtkImport->CopyImportVoidPointer(vImageBufferForVtk,vTotalSize*sizeof(short));
vtkImport->Update();
vtkSmartPointer<vtkImageData> vImage = vtkImport->GetOutput();
vtkImport->Delete();
short vPixel = *static_cast<short*>(vImage->GetScalarPointer(maxx, maxy, maxz));
std::cerr << " max pixel value:" << vPixel << std::endl;
return vImage;
The vPixel assignment will segv above.
I think the CopyImportVoidPointer essentially uses SetImportVoidPointer with the save option of 0 (2nd parameter in SetImportVoidPointer).
So for now, i have to make a new buffer and use SetImportVoidPointer(vImageBufferForVtk,1) as shown below. I recommend adding a save option to the CopyImportVoidPointer with default of 1 to avoid referencing freed memory issues.
vtkImageImport *vtkImport = vtkImageImport::New();
vtkImport->SetWholeExtent(0, src.Size(MX4::Dim1) - 1, 0, src.Size(MX4::Dim2) - 1, 0, src.Size(MX4::Dim3) - 1);
int maxx = src.Size(MX4::Dim1)-1;
int maxy = src.Size(MX4::Dim2)-1;
int maxz = src.Size(MX4::Dim3)-1;
vtkImport->SetDataExtentToWholeExtent();
vtkImport->SetDataScalarTypeToShort();
vtkImport->SetNumberOfScalarComponents(1);
int vTotalSize = src.Size(MX4::Dim1) * src.Size(MX4::Dim2) * src.Size(MX4::Dim3);
// Allocate the pixel buffer for vtk to own.
short *vImageBufferForVtk = new short[vTotalSize];
short *srcPixel = src.Data();
for (int i = 0;i < vTotalSize;i++)
{
vImageBufferForVtk[i] = *srcPixel++;
}
vtkImport->SetImportVoidPointer(vImageBufferForVtk,1);
vtkImport->Update();
vtkSmartPointer<vtkImageData> vImage = vtkImport->GetOutput();
vtkImport->Delete();
short vPixel = *static_cast<short*>(vImage->GetScalarPointer(maxx, maxy, maxz));
std::cerr << " max pixel value:" << vPixel << std::endl;