bugGNU Octave - Bugs: bug #49756, Crash when panning an image to top...

 
 

bug #49756: Crash when panning an image to top of axes

Submitter:  None
Submitted:  Fri 02 Dec 2016 06:53:13 PM UTC
   
 
Category:  Plotting with OpenGL Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Segfault, Bus Error, etc.
Status:  Fixed Assigned to:  None
Originator Name:  Marshall Originator Email:  -email is unavailable-
Open/Closed:  * Closed Release:  * dev
Operating System:  * Microsoft Windows Fixed Release:  None
Planned Release:  None
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Thu 01 Nov 2018 03:36:55 PM UTC, comment #18: 

@marsian: This is a know issue which is already reported in bug #42435.

Pantxo Diribarne <pantxo>
Group Member
Tue 30 Oct 2018 11:34:39 PM UTC, comment #17: 

I've tried the new dev version, and it seems to have fixed the crash reported as the primary bug of the original report. It also fixes the majority of the other test cases, such as the disappearing image when moved outside of the axis.

The first half of the original example still has problems with not drawing partial pixels. Maybe there should be a separate bug report created? bug #49490 mentioned in comment #3 seems to be different to me, but isn't fixed either.


%"pixels" disappear when not completely within the axis (zoom or scroll)
figure(1),clf
im=uint8(rand(100,100)*255);
imshow(im)
hold on;
xs=[0 0 1 1 0];ys=[0 1 1 0 0];
xoff=xs-0.5;yoff=ys-0.5;
offset=50;
plot(xs+offset,ys+offset,'rx')
plot(xoff*0.75+0.5+offset,yoff*0.75+0.5+offset,'b')
hold off;
title('nice image')
pause(1)
axc=([0 1 0 1]-.5);
axis(axc*2+.5+offset)%zoom: partial pixels not shown
title('Partial image, whole pixels only')
pause(1)
axc=([0 1 0 1]-.75);
axis(axc*2+.5+offset)%zoom: partial pixels not shown
title('Partial image, whole pixels only, due to pan')
pause(1)
axc=([0 1 0 1]-.5);
axis(axc+offset+.5)%zoom more: no pixels shown (background color), plot is.
title('no image, no background (only plot), due to zoom')


Marshall <marsian>
Tue 30 Oct 2018 03:55:51 PM UTC, comment #16: 

@Pantxo: I pushed your patch here https://hg.savannah.gnu.org/hgweb/octave/rev/221c039aa415.

I made one simplification which was to use std::swap to interchange elements rather than doing it by hand with an intermediate variable.  See the diff below.


diff -r 05dccc7fdb9f libinterp/corefcn/gl-render.cc
--- a/libinterp/corefcn/gl-render.cc        Sun Oct 28 21:56:40 2018 +0100
+++ b/libinterp/corefcn/gl-render.cc        Tue Oct 30 08:48:12 2018 -0700
@@ -3780,9 +3780,7 @@ namespace octave
     bool xflip = false;
     if (x(0) > x(1))
       {
-        double tmp = x(0);
-        x(0) = x(1);
-        x(1) = tmp;
+        std::swap (x(0), x(1));
         xflip = true;
       }
     else if (w > 1 && x(1) == x(0))
@@ -3791,9 +3789,7 @@ namespace octave
     bool yflip = false;
     if (y(0) > y(1))
       {
-        double tmp = y(0);
-        y(0) = y(1);
-        y(1) = tmp;
+        std::swap (y(0), y(1));
         yflip = true;
       }
     else if (h > 1 && y(1) == y(0))
@@ -3856,7 +3852,6 @@ namespace octave
         if (im_xmax > xmax)
           j1 -= (im_xmax - xmax)/nor_dx;

-
         if (im_ymin < ymin)
           i0 += (ymin - im_ymin)/nor_dy + 1;
         if (im_ymax > ymax)


Thanks for the large number of graphics patches you have submitted recently.  Marking this bug as fixed and closing report.


Rik <rik5>
Group administrator
Sun 28 Oct 2018 09:10:16 PM UTC, comment #15: 

I attached a patch that makes Octave behave as Matlab (when x/ydata are permutted, the image is displayed flipped) and fixes the clipping issues that I observed.

(file #45319)

Pantxo Diribarne <pantxo>
Group Member
Sat 27 Oct 2018 04:19:14 PM UTC, comment #14: 

It still crashes on 4.4.1

Marshall <marsian>
Fri 26 Oct 2018 06:50:53 AM UTC, comment #13: 

@Rik: We also need to flip the image since xdata(1) indicates the position of the first column of cdata and xdata(end) indicates the position of the last column of cdata (same for ydata with rows).

Pantxo Diribarne <pantxo>
Group Member
Fri 26 Oct 2018 01:24:30 AM UTC, comment #12: 

Can you just put std::abs around the calculation so it doesn't matter whether y(0) or y(1) is larger?  Also, it looks like the same situation could happen for the x-axis.  Maybe std::abs again?


     if (w > 1)
       {
         pix_dx = (p1(0) - p0(0)) / (w-1);
         nor_dx = (x(1) - x(0)) / (w-1);
       }
     else
       {
         const ColumnVector p1w = xform.transform (x(1) + 1, y(1), 0);
         pix_dx = p1w(0) - p0(0);
         nor_dx = 1;
       }

     if (h > 1)
       {
         pix_dy = (p1(1) - p0(1)) / (h-1);
         nor_dy = (y(1) - y(0)) / (h-1);
       }
     else
       {
         const ColumnVector p1h = xform.transform (x(1), y(1) + 1, 0);
         pix_dy = p1h(1) - p0(1);
         nor_dy = 1;
       }



Rik <rik5>
Group administrator
Thu 25 Oct 2018 11:51:06 AM UTC, comment #11: 

@Markus: thanks, in the mean time I asked on the maintainers list

http://octave.1599824.n4.nabble.com/Request-for-test-in-Matlab-td4689781.html

So it looks like Matlab accepts "inverted" x/ydata for image objects and displays the image flipped when ydata=[ymax ymin].

Pantxo Diribarne <pantxo>
Group Member
Thu 25 Oct 2018 10:58:29 AM UTC, comment #10: 

Results in Matlab R2016a:

>> figure
>> h = image (rand (20, 20, 3));
ylim (gca)
set (h, 'ydata', [20 1]); %error?
get (h, 'ydata')
ylim (gca)

ans =

    0.5000   20.5000


ans =

    20     1


ans =

    0.5000   20.5000


No error message nor warning.

Markus Mützel <mmuetzel>
Group administrator
Wed 24 Oct 2018 07:36:22 PM UTC, comment #9: 

In opengl_renderer::draw_image (https://octave.org/doxygen/4.4/dd/d82/gl-render_8cc_source.html#l03609) we compute the pixel size in screen-pixels and normalized units


if (h > 1)
 {
   pix_dy = (p1(1) - p0(1)) / (h-1);
   nor_dy = (y(1) - y(0)) / (h-1);
 }
...


using ydata. This results in negative pixel size if ydata=[ymax ymin].
 
I think "get (gca, "ylim")" always returns [ymin ymax] whatever the "ydir", and images should also do the same.

It would be interesting to test the following in Matlab


h = image (rand (20, 20, 3));
ylim (gca)
set (h, 'ydata', [20 1]); %error?
get (h, 'ydata')
ylim (gca)


Pantxo Diribarne <pantxo>
Group Member
Wed 24 Oct 2018 07:12:04 PM UTC, comment #8: 

Where in gl-render.cc is the code making the bad assumption about the ordering relation between y(0) and y(1)?

This might have something to do with the axes "ydir" property which is usually set to "reverse" for images.

Rik <rik5>
Group administrator
Wed 24 Oct 2018 03:47:40 PM UTC, comment #7: 

Sorry, replace ">" by "<" and vice-versa in my previous post.

Pantxo Diribarne <pantxo>
Group Member
Wed 24 Oct 2018 03:45:17 PM UTC, comment #6: 

After trying the crashing example again, I can see something wrong on linux too: even though this doesn't lead to a crash, the clipping of the image is wrong when I pan/drag the image.

FTR, the problematic example is:


close all
im=uint8(rand(495,495)*255);
imx0 = 60;
imy0 = 70;
imxf = 442;
imyf = 452;
imxF = 9;
imyF = 3000;
imshow(im,'xdata',([1,size(im,1)]-imx0)*imxF/(imxf-imx0),'ydata',([size(im,2),1]-imy0)*imyF/(imyf-imy0))
axis('on','xy','normal')


The origin of the issue is that the opengl renderer assumes ydata(1) > ydata(2) and it is a wrong assumption in this example.

I don't know if ML allows ydata(1) < ydata(2) but I'd be tempted to disallow that or silently invert those data. Thoughts?

Pantxo Diribarne <pantxo>
Group Member
Wed 24 Oct 2018 11:30:23 AM UTC, comment #5: 

@Marsian: Can you test you crashing example on the current Ovtave 4.4.1 (the OpenGL driver changed, we never know).

Pantxo Diribarne <pantxo>
Group Member
Thu 08 Dec 2016 06:41:00 PM UTC, comment #4: 

I can't get any of the following variations to crash except for the last one, which will always crash (eventually), although not on the first try to drag. If I drag slow it doesn't seem to crash, but quick movements seem to cause it. I crash it by panning the figure up out of the axis to the top of the screen in one fast motion (or after several tries). I tried all of these on Windows 10, but I first reported this bug based on Windows 7: so I can get it to crash every time on two different machines.


%No crash
close all
graphics_toolkit qt
image

%No crash:
close all
image
axis('on','xy','normal')

%No crash:
close all
im=uint8(rand(495,495)*255);
imx0 = 60;
imy0 = 70;
imxf = 442;
imyf = 452;
imxF = 9;
imyF = 3000;
imshow(im,'xdata',([1,size(im,1)]-imx0)*imxF/(imxf-imx0),'ydata',([size(im,2),1]-imy0)*imyF/(imyf-imy0))

%No crash:
close all
im=uint8(rand(495,495)*255);
imshow(im)
axis('on','xy','normal')

%crash on drag to top (eventually, not always first time on drag):
close all
im=uint8(rand(495,495)*255);
imx0 = 60;
imy0 = 70;
imxf = 442;
imyf = 452;
imxF = 9;
imyF = 3000;
imshow(im,'xdata',([1,size(im,1)]-imx0)*imxF/(imxf-imx0),'ydata',([size(im,2),1]-imy0)*imyF/(imyf-imy0))
axis('on','xy','normal')


Marshall <marsian>
Mon 05 Dec 2016 10:16:19 PM UTC, comment #3: 

Image pixels which are partially outside the axis are not drawn.  See bug #49490.

Octave shouldn't crash though.  Can you reproduce it with this simpler example?


close all
graphics_toolkit qt
image
## Now select pan on plot window
## Move image around, up and off screen, etc.



Rik <rik5>
Group administrator
Sat 03 Dec 2016 01:50:38 PM UTC, comment #2: 

Confirmed with 4.3.0+ as well.

Release -> dev
Status -> confirmed

Philip Nienhuis <philipnienhuis>
Group Member
Fri 02 Dec 2016 10:36:38 PM UTC, comment #1: 

On linux I have confirmed problems 1 and 2, but problem 3 does not occur, i.e., no crash.  There is actually a 4th problem, which is what you wrote in the message: the image is appearing below the axis and not being cropped.

For comparison, the gnuplot graphics toolkit works in terms of image borders and pixel zoom.  (Generally, panning doesn't seem to work in gnuplot, but it should be possible.)  However, your first example fails when trying to overlay the box and points on the 2x2 center pixel block.  So I have created another bug report for that:  https://savannah.gnu.org/bugs/index.php?49757


Dan Sebald <sebald>
Fri 02 Dec 2016 06:53:13 PM UTC, original submission:  

I'm using GNU Octave, version 4.2.0, "x86_64-w64-mingw32".
I have several problems related to imshow(). First is that imshow() will not draw partial pixels when zooming or panning; second, under some conditions, the entire image doesn't show when the top of the image is not within the axis; third, I can reproducibly crash octave when panning/dragging the image up to the top of the screen.

Obviously the crash has the worst consequences, but problem 2 is what made me start the bug report. Trying to extract the bare-bones of the problem led to problem 1, which doesn't reproduce problem 2. I found problem 3 on accident while trying to create and test this bug report.


%"pixels" disappear when not completely within the axis (zoom or scroll)
figure(1),clf
im=uint8(rand(100,100)*255);
imshow(im)
hold on;
xs=[0 0 1 1 0];ys=[0 1 1 0 0];
xoff=xs-0.5;yoff=ys-0.5;
offset=50;
plot(xs+offset,ys+offset,'rx')
plot(xoff*0.75+0.5+offset,yoff*0.75+0.5+offset,'b')
hold off;
title('nice image')
pause(1)
axc=([0 1 0 1]-.5);
axis(axc*2+.5+offset)%zoom: partial pixels not shown
title('Partial image, whole pixels only')
pause(1)
axis(axc+offset+.5)%zoom more: no pixels shown (background color), plot is.
title('no image, no background (only plot)')

pause(1)
%Whole image disappears when top corners above top axis (zoom or scroll)
% (and image shown below bottom of axis, when bottom is beyond bottom axis and top not above the top axis)
im=uint8(rand(495,495)*255);
figure(2),clf
imx0 = 60;
imy0 = 70;
imxf = 442;
imyf = 452;
imxF = 9;
imyF = 3000;
imshow(im,'xdata',([1,size(im,1)]-imx0)*imxF/(imxf-imx0),'ydata',([size(im,2),1]-imy0)*imyF/(imyf-imy0))
axis('on','xy','normal')
ax=axis;
title('nice image')
pause(1);
axis(ax*0.99)%zoom: whole image disappears
title('NO IMAGE!')
pause(1);
axis(ax*0.99+[0 0 +100 +100])%scroll: reappears, but extends below bottom axis
title('Back again! (but below bottom axis)')
pause(1);
axis(ax*0.99)%Scroll back: whole image disappears again.
title('Gone again!')
pause(1);
title('Now lets manually crash octave')
pause(1);
title('manually pan the image to the top of the screen (keep dragging beyond figure border)')
pan on


Anonymous

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

Attached Files
file #45319:  xydata_flip.patch added by pantxo (8KiB - text/x-patch)

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by mmuetzel (Posted a comment)
  • -email is unavailable- added by pantxo (Posted a comment)
  • -email is unavailable- added by marsian (Posted a comment)
  • -email is unavailable- added by rik5 (Posted a comment)
  • -email is unavailable- added by sebald (Posted a comment)
  • -email is unavailable- added by None (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only group members can vote.

     

    Follow 10 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2018-10-30 rik5 StatusPatch Submitted Fixed
        Open/ClosedOpen Closed
    2018-10-28 pantxo Attached File- Added xydata_flip.patch, #45319
        StatusConfirmed Patch Submitted
    2018-10-26 pantxo StatusNeed Info Confirmed
    2018-10-24 pantxo StatusConfirmed Need Info
    2016-12-05 rik5 CategoryPlotting Plotting with OpenGL
        SummaryPartial or no image shown with imshow, plus consistent Octave crash Crash when panning an image to top of axes
    2016-12-03 philipnienhuis StatusNone Confirmed
        Release4.2.0 dev

    Back to the top

    Powered by Savane 3.13-d3ae.
    Corresponding source code