[vtk-developers] Possible fix for vtkImageStencilData::InsertAndMergeExtent
Xabi Riobe
xabivtk at gmail.com
Tue Sep 22 11:43:28 EDT 2015
Hi David,
here is a sample that reproduce the crash, plus another one found recently.
both are related to the use of vtkImageStencilData::Subtract
you can compile ImageStencil.cxx with CMakeLists.txt (providing VTK_DIR in
Cmake gui) and the proposed fixes are in vtkImageStencilFixed-VTK6.h that
you can activate by uncommenting the defines FIX1 & FIX2 at the beginning
of the sample.
some comments are included in the .h close to the code fix (look for #ifdef
FIX).
The first crash (FIX1 in vtkImageStencilData::InsertAndMergeExtent) only
occurs with Mac because it is related to the access of a wrong memory
location pointing to a value that is always negative on Windows, passing
the " while(condition) " , whereas on Mac the value can be positive. This
happens when the insertion must be at the beginning of the list.
For that reason, it is not always reproductible even on Mac, but you should
get it with less than 10 executions.
The second one (FIX2 in vtkImageStencilData::RemoveExtent) is always
reproductible in both Mac/Windows and is related to the bad ordering of
some elements in a list that causes an infinite loop later in the execution.
Both crashes appear randomly later in the code, not at the location of the
fixes.
Let me know if you want me to test other cases or need more information.
2015-07-30 19:18 GMT+02:00 David Gobbi <david.gobbi at gmail.com>:
> Hi Xabi,
>
> It doesn't look like the right fix, I suspect that the flaw in the logic
> is somewhere else in that method. Do you have any test code that I can use
> to reproduce the bug?
>
> - David
>
>
> On Thu, Jul 30, 2015 at 1:05 AM, Xabi Riobe <xabivtk at gmail.com> wrote:
>
>> Hi,
>>
>> I'm in the process of migrating from 5.10.1 to 6.3 and have found a fix i
>> had in vtkImageStencilData::InsertAndMergeExtent from one year ago.
>>
>> at the end of the method there is this loop:
>>
>> while (r1 < clist[insertIndex-1])
>> {
>> clist[insertIndex] = clist[insertIndex-2];
>> clist[insertIndex+1] = clist[insertIndex-1];
>> insertIndex -= 2;
>> }
>>
>> and i have this line added : if (insertIndex <= 1) break;
>> with the comment: "avoid accessing out of range elements, which produces
>> incorrect stencil that causes a random crash later when used in
>> vtkImageStencilExecute"
>>
>> This random crash occured on Mac, never reproduced on Windows.
>>
>> I was wondering if by looking at the code you think it's a correct fix
>> that can be merged.
>>
>> Thanks
>>
>> Xabi.
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/vtk-developers/attachments/20150922/62a856d7/attachment-0001.html>
-------------- next part --------------
cmake_minimum_required(VERSION 2.8)
PROJECT(ImageStencil)
find_package(VTK REQUIRED)
include(${VTK_USE_FILE})
add_executable(ImageStencil MACOSX_BUNDLE ImageStencil)
if(VTK_LIBRARIES)
target_link_libraries(ImageStencil ${VTK_LIBRARIES})
else()
target_link_libraries(ImageStencil vtkHybrid vtkWidgets)
endif()
-------------- next part --------------
#include <cstdlib>
#include <vtkVersion.h>
#include <vtkImageData.h>
#include <vtkImageMapper3D.h>
#include <vtkImageStencil.h>
#include <vtkImageStencilData.h>
#include <vtkImageToImageStencil.h>
#include <vtkSmartPointer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleImage.h>
#include <vtkRenderer.h>
#include <vtkImageActor.h>
//#define FIX1 // Uncomment to fix bug 1
//#define FIX2 // Uncomment to fix bug 2
#if defined(FIX1) || defined(FIX2)
#include "vtkImageStencilFixed-VTK6.h"
#define vtkImageStencilData vtkImageStencilDataFixed
#endif
static void CreateColorImage(vtkImageData*, unsigned int channel);
static void CreateMask(vtkImageData*, int, int, int, int, int, int);
int main(int, char *[])
{
vtkSmartPointer<vtkImageData> image1 = vtkSmartPointer<vtkImageData>::New();
CreateColorImage(image1, 0); // Create a red image
vtkSmartPointer<vtkImageData> mask = vtkSmartPointer<vtkImageData>::New();
CreateMask(mask, 10, 10, 10, 3, 3, 3);
vtkSmartPointer<vtkImageStencilData> stencilData = vtkSmartPointer<vtkImageStencilData>::New();
vtkSmartPointer<vtkImageToImageStencil> imageToImageStencil = vtkSmartPointer<vtkImageToImageStencil>::New();
imageToImageStencil->SetInputData(mask);
imageToImageStencil->ThresholdByUpper(122);
imageToImageStencil->Update();
stencilData->Add(imageToImageStencil->GetOutput());
{
vtkSmartPointer<vtkImageData> mask = vtkSmartPointer<vtkImageData>::New();
CreateMask(mask, 6, 6, 6, 2, 2, 2);
vtkSmartPointer<vtkImageToImageStencil> imageToImageStencil = vtkSmartPointer<vtkImageToImageStencil>::New();
imageToImageStencil->SetInputData(mask);
imageToImageStencil->ThresholdByUpper(122);
imageToImageStencil->Update();
stencilData->Add(imageToImageStencil->GetOutput());
}
{
vtkSmartPointer<vtkImageData> mask = vtkSmartPointer<vtkImageData>::New();
CreateMask(mask, 7, 7, 7, 1, 1, 1);
vtkSmartPointer<vtkImageToImageStencil> imageToImageStencil = vtkSmartPointer<vtkImageToImageStencil>::New();
imageToImageStencil->SetInputData(mask);
imageToImageStencil->ThresholdByUpper(122);
imageToImageStencil->Update();
stencilData->Subtract(imageToImageStencil->GetOutput());
}
vtkSmartPointer<vtkImageStencil> stencil = vtkSmartPointer<vtkImageStencil>::New();
stencil->SetStencilData(stencilData);
stencil->ReverseStencilOn();
stencil->SetBackgroundValue(0.0);
stencil->SetInputData(image1);
stencil->Update();
// Create an actor
vtkSmartPointer<vtkImageActor> actor = vtkSmartPointer<vtkImageActor>::New();
actor->GetMapper()->SetInputConnection(stencil->GetOutputPort());
// Setup renderer
vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
renderer->AddActor(actor);
renderer->ResetCamera();
// Setup render window
vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(renderer);
// Setup render window interactor
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
// Render and start interaction
renderWindowInteractor->SetRenderWindow(renderWindow);
renderWindow->Render();
#ifdef __APPLE__
renderWindow->SetPosition(50, 50);
#endif
renderWindowInteractor->Start();
return EXIT_SUCCESS;
}
void CreateColorImage(vtkImageData* image, const unsigned int channel)
{
unsigned int dim = 20;
image->SetDimensions(dim, dim, dim);
image->AllocateScalars(VTK_UNSIGNED_CHAR,3);
for(unsigned int x = 0; x < dim; x++)
{
for(unsigned int y = 0; y < dim; y++)
{
for(unsigned int z = 0; z < dim; z++)
{
unsigned char* pixel = static_cast<unsigned char*>(image->GetScalarPointer(x,y,z));
pixel[0] = 0;
pixel[1] = 0;
pixel[2] = 0;
pixel[channel] = 255;
}
}
}
image->Modified();
}
static void CreateMask(vtkImageData* image, int px, int py, int pz, int w, int h, int d)
{
unsigned int dim = 20;
image->SetDimensions(dim, dim, dim);
image->AllocateScalars(VTK_UNSIGNED_CHAR, 1);
for(unsigned int x = 0; x < dim; x++)
{
for(unsigned int y = 0; y < dim; y++)
{
for(unsigned int z = 0; z < dim; z++)
{
unsigned char* pixel = static_cast<unsigned char*>(image->GetScalarPointer(x,y,z));
//if(x < px - w || x > px + w || y < py - h || y > py + h || z < pz - d || z > pz + d)
if(abs(int(x) - px) + abs(int(y) - py) + abs(int(z) - pz) > int(w + h + z))
{
pixel[0] = 0;
}
else
{
pixel[0] = 255;
}
}
}
}
image->Modified();
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: vtkImageStencilFixed-VTK6.h
Type: text/x-chdr
Size: 14794 bytes
Desc: not available
URL: <http://public.kitware.com/pipermail/vtk-developers/attachments/20150922/62a856d7/attachment-0001.h>
More information about the vtk-developers
mailing list