GNOME Bugzilla – Bug 598985
Perspective tool incorrect results, memory overflow
Last modified: 2012-06-17 19:02:40 UTC
Created attachment 145807 [details] Photo that produces undesired effects when corrected for perspective When performing a perspective correction on the attached image, the results are unpredictable and never correct. Steps to reproduce: 1) Open the attached image 2) Use the Perspective tool 3) Select Corrective (backwards) direction 4) Drag the corners of the image to the corners of the sidewalk tile containing the drawing, two of which are off the edge of the image and should be estimated 5) Click Transform Possible results, pseudo-random in occurrence: 1) The main GIMP window becomes nonresponsive, CPU usage goes to 100%, the status bar does not show a progress bar for the Perspective Correction, nothing else happens until GIMP is killed. 2) The main GIMP window becomes nonresponsive, CPU usage goes to 100%, the progress bar appears and fills to completion, but does not go away, nothing else happens until GIMP is killed. 3) as (1) or (2), but with unbounded memory usage growth 4) The perspective transformation completes, but only a small part of the image, wildly skewed, is preserved 5) as (4), but with the resulting layer wildly resized and far outside the image boundaries
The trigger for this behavior is that 'Clipping' is set to 'Adjust' and the inverse transform has a horizon singularity such that the upper right corner of the original source rectangle is projected past positive infinity and wraps around, reappearing on the negative side. You can see this in the math from the fact that the 'w' term passes through zero and goes negative in the projection calculation. This is resulting in an absurdly large transform boundary. Thus, the 'adjust' setting is requesting an impossible result. There is already code in gimp_transform_resize_boundary expecting this 'error' (checking to see if the projected corners are FINITE(), but there's no portable way in C89 to set a double to +/-Inf or NAN for that matter, and code in transform_point avoids any exception so the FINITE() checks in gimp_transform_resize_boundary will never trigger. Would the proper thing to do be to check for an impossible transform out of band (a new libgimpmath call?) and drop back to 'GIMP_TRANSFORM_RESIZE_CLIP' in that case?
Oh, I forgot to note: selecting the 'Clip' option in the dropdown menu avoids the singularity and the transform succeeds.
I trust Alexis' elaborate analysis in bug #316479 and resolve this one a a duplicate. *** This bug has been marked as a duplicate of bug 316479 ***