MantisBT - VTK
View Issue Details
0011613VTK(No Category)public2010-12-16 09:292012-12-12 12:19
John Stark. 
David Gobbi 
normalminoralways
closedfixed 
 
5.10.0 
0011613: vtkOpenGLImageActor hangs if image is empty.
When an empty image is passed to the vtkOpenGLImageActor, the MakeDataSuitable method can enter an infinite loop, and hang.

The problem only occurs when the image returns it's extents as [0, -1, 0, -1, 0, -1]. In this case, the xsize is inferred to be -1, and the loop to find the next power of 2 falls into an infinite loop.
The problem occurs here :
    xsize = ext[xdim*2+1] - ext[xdim*2] + 1;
    // xsize and ysize must be a power of 2 in OpenGL
    xs = static_cast<unsigned short>(xsize);
    while (!(xs & 0x01))
      {
      xs = xs >> 1;
      }

If xs is zero, the loop never terminates.
Please can you add an additional test that both xsize and ysize are > zero :
diff --git a/Rendering/vtkOpenGLImageActor.cxx b/Rendering/vtkOpenGLImageActor.cxx
index 172b82a..79ee1a8 100644
--- a/Rendering/vtkOpenGLImageActor.cxx
+++ b/Rendering/vtkOpenGLImageActor.cxx
@@ -154,9 +154,12 @@ unsigned char *vtkOpenGLImageActor::MakeDataSuitable(int &xsize, int &ysize,
     xsize = ext[xdim*2+1] - ext[xdim*2] + 1;
     // xsize and ysize must be a power of 2 in OpenGL
     xs = static_cast<unsigned short>(xsize);
- while (!(xs & 0x01))
+ if (xsize > 0)
       {
- xs = xs >> 1;
+ while (!(xs & 0x01))
+ {
+ xs = xs >> 1;
+ }
       }
     if (xs == 1)
       {
@@ -170,9 +173,12 @@ unsigned char *vtkOpenGLImageActor::MakeDataSuitable(int &xsize, int &ysize,
     ysize = (this->ComputedDisplayExtent[ydim*2+1] -
              this->ComputedDisplayExtent[ydim*2] + 1);
     ys = static_cast<unsigned short>(ysize);
- while (!(ys & 0x01))
+ if (ysize > 0)
       {
- ys = ys >> 1;
+ while (!(ys & 0x01))
+ {
+ ys = ys >> 1;
+ }
       }
     // yes it is a power of two already
     if (ys == 1)
No tags attached.
Issue History
2010-12-16 09:29John Stark.New Issue
2010-12-16 09:55David GobbiAssigned To => David Gobbi
2010-12-16 09:55David GobbiStatusbacklog => tabled
2010-12-16 10:23David GobbiNote Added: 0024208
2010-12-16 10:37David GobbiStatustabled => @80@
2010-12-16 10:37David GobbiResolutionopen => fixed
2012-12-12 12:19David GobbiStatuscustomer review => closed
2012-12-12 12:19David GobbiFixed in Version => 5.10.0

Notes
(0024208)
David Gobbi   
2010-12-16 10:23   
Those loops should not be there at all, there is an easier way to check if the dimensions are a power of two:

// check whether dimensions are a power of two
if (xsize > 0 && (xsize & (xsize-1)) == 0 &&
     ysize > 0 && (ysize & (ysize-1)) == 0)
  {
  }

Subtracting one from a non-zero value causes the lowest set bit to be cleared. If the lowest set bit is the only set bit (as is the case only for a power-of-two), then all set bits will be cleared, and (x & (x-1)) will be zero.

Therefore, (xsize & (xsize-1)) == 0 if and only if xsize is a power of two or is zero.

I have pushed commit 6cd830040010eef56af491906a0f58b8cc3a367d to fix this bug.