Uninitialized information variables in image filters are causing crashes
This issue was created automatically from an original Mantis Issue. Further discussion may take place here.
vtkImageResliceMapper has several uninitialized variables, for example in the GetIndexMatrix function. There the variables inOrigin, inSpacing, outOrigin and outSpacing are declared and then filled via inInfo->Get(vtkDataObject::SPACING(), inSpacing) and so on. These calls don't succeed in every case though, so that some of the variables can be left uninitialized. The same thing can happen in the RequestInformation function (inSpacing, inOrigin, inWholeExt, outSpacing, outOrigin, outWholeExt, maxBounds).
Leaving the variables in an uninitialized state causes the filter to misbehave. The following program demonstrates this:
#include "vtkBMPWriter.h"
#include "vtkCommand.h"
#include "vtkImageReslice.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkSmartPointer.h"
#include "vtkSmartVolumeMapper.h"
#include "vtkStructuredPointsReader.h"
#include "vtkVolume.h"
#include "vtkWindowToImageFilter.h"
class MyCallBack: public vtkCommand
{
public:
static MyCallBack *New()
{
return new MyCallBack;
}
virtual void Execute(vtkObject* caller, unsigned long eventId, void* callData)
{
if (eventId != vtkCommand::KeyPressEvent) return;
vtkRenderWindowInteractor* interactor = static_cast<vtkRenderWindowInteractor*>(caller);
if (interactor == NULL) return;
char* pressedKey = interactor->GetKeySym();
if (strcmp(pressedKey, "9") == 0)
{
windowToImageFilter->Modified();
bitmapWriter->SetFileName("ImageResliceBug.bmp");
bitmapWriter->Write();
}
}
vtkSmartPointer<vtkWindowToImageFilter> windowToImageFilter;
vtkSmartPointer<vtkBMPWriter> bitmapWriter;
};
int main()
{
vtkSmartPointer<vtkStructuredPointsReader> pointsReader = vtkSmartPointer<vtkStructuredPointsReader>::New();
pointsReader->SetFileName("ironProt.vtk");
pointsReader->Update();
vtkSmartPointer<vtkSmartVolumeMapper> smartMapper = vtkSmartPointer<vtkSmartVolumeMapper>::New();
smartMapper->SetInputConnection(pointsReader->GetOutputPort());
vtkSmartPointer<vtkVolume> volume = vtkSmartPointer<vtkVolume>::New();
volume->SetMapper(smartMapper);
vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
vtkSmartPointer<vtkRenderWindowInteractor> interactor= vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindow->AddRenderer(renderer);
renderWindow->SetSize(500, 300);
renderWindow->SetPosition(100, 100);
interactor->SetRenderWindow(renderWindow);
renderer->AddActor(volume);
renderer->SetBackground(1.0, 1.0, 1.0);
vtkSmartPointer<vtkWindowToImageFilter> windowToImageFilter = vtkSmartPointer<vtkWindowToImageFilter>::New();
windowToImageFilter->SetInput(renderWindow);
vtkSmartPointer<vtkImageReslice> imageReslice = vtkSmartPointer<vtkImageReslice>::New();
imageReslice->SetInputConnection(windowToImageFilter->GetOutputPort());
vtkSmartPointer<vtkBMPWriter> bitmapWriter = vtkSmartPointer<vtkBMPWriter>::New();
bitmapWriter->SetInputConnection(imageReslice->GetOutputPort());
vtkSmartPointer<MyCallBack> callback = vtkSmartPointer<MyCallBack>::New();
callback->bitmapWriter = bitmapWriter;
callback->windowToImageFilter = windowToImageFilter;
interactor->AddObserver("KeyPressEvent", callback);
// Let's go
renderWindow->Render();
interactor->Start();
}
Pressing '9' will attempt to write a bitmap to file and crashes with an access violation in vtkWindowToImageFilter.cxx on line 484 on my machine (I'm using VTK 6.2 on windows using the OpenGL2 backend).
I suspect this crash doesn't happen if you set the spacing/origin etc in the reslice filter, but this wasn't necessary in VTK 5.10. Even if this is now required, forgetting this shouldn't cause a crash. Initializing the values to things like {0.0, 0.0, 0.0} for the origin and {1.0, 1.0, 1.0} for the spacing etc fixes the problem for me.
When you try to reproduce this issue, don't use a debug build of VTK, because then the variables are automatically initialized to sane values and don't contain random values (at least on windows).