After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 316479 - The Perspective Tool creates an empy image instead of transforming it
The Perspective Tool creates an empy image instead of transforming it
Product: GIMP
Classification: Other
Component: Tools
git master
Other All
: Normal normal
: 2.10
Assigned To: GIMP Bugs
: 598985 (view as bug list)
Depends on:
Reported: 2005-09-16 14:55 UTC by tobias
Modified: 2016-11-08 18:33 UTC
See Also:
GNOME target: ---
GNOME version: ---

An test image(JPEG) to show this bug. (12.41 KB, image/jpeg)
2005-09-16 14:57 UTC, tobias
math (151.11 KB, application/pdf)
2012-06-17 18:48 UTC, Alexis Wilhelm
testcase (1.92 KB, text/x-scheme)
2012-06-18 16:39 UTC, Massimo
patch (3.58 KB, patch)
2012-06-20 05:45 UTC, Alexis Wilhelm
none Details | Review
patch against gimp/master (4.01 KB, patch)
2012-07-01 13:10 UTC, Alexis Wilhelm
committed Details | Review
patch against gegl/master (3.91 KB, patch)
2012-07-01 13:10 UTC, Alexis Wilhelm
rejected Details | Review

Description tobias 2005-09-16 14:55:36 UTC
Please describe the problem:
The Perspective Tool doesn't work like expected.

Steps to reproduce:
1. Open the image I'll attach.
2. Click on the Perspective Tool (Shift+P).
3. Set Transform Direction to Backward(corrective).
4. Set the transform grid to the red lines.
5. Transform.

Actual results:

Expected results:

Does this happen every time?

Other information:
Comment 1 tobias 2005-09-16 14:57:12 UTC
Created attachment 52315 [details]
An test image(JPEG) to show this bug.
Comment 2 Michael Natterer 2005-09-16 16:01:52 UTC
Indeed, that is very very broken.
Comment 3 weskaggs 2005-10-04 21:24:02 UTC
Using the perspective tool in corrective mode means having to invert a matrix. 
There is nothing to prevent the matrix from being singular or nearly so.  If
this happens, it's a bad situation -- like dividing by something nearly zero. 
Maybe the best approach is for the tool to calculate the determinant of the
matrix before trying to transform, and bailing out with a warning message if the
value is too close to zero.  (I'm not certain this is what is happening, but
judging by the way it is going wrong, I would bet at least a nickel on it.)
Comment 4 weskaggs 2005-10-13 16:29:03 UTC
I have looked into this a bit more.  I had been assuming that the perspective
tool does a linear transformation, but I should have thought more deeply: 
linear transformations only give 6 degrees of freedom, and the perspective tool
requires 8 -- two coordinates for each of the four vertices.  It manages this by
including a hyperbolic (1/x) component in the transform; see
gimp_matrix3_transform().  Now the problem is that it is easy for hyperbolic
things to blow up, and it is hard to predict when this will happen for the
perspective tool.  When it blows up, the result is that the transformed layer
becomes extremely large.

The appropriate fix, I think, is that the function
gimp_drawable_transform_tiles_affine() should do some sanity checking after it
calculates the corners of the transformed layer -- currently it only checks that
they are finite, but it probably should clip them to some multiple of the image
size instead.  Also there should be an additional sanity check to verify that
none of the interior points in the region will map to infinity.

In any case, the example given in this bug report is not actually a bug -- what
is happening is that the layer is being shifted such that none of its contents
lie within the image bounds.  (In fact, it is being shifted such that one of its
interior points maps to infinity.)  This kind of thing is going to happen
sometimes when the perspective tool is used in inverse mode.  The real bug is
that some control matrices can give rise to extremely large transformed layers
and cause GIMP either to crash or to thrash.
Comment 5 Sven Neumann 2006-08-22 16:27:04 UTC
That's exactly the reason that "Clip result" in on by default in the Perspective transform tool.
Comment 6 Sven Neumann 2007-02-05 17:39:57 UTC
Doesn't seem to make sense to have this bug sitting on the 2.2 milestone.
Comment 7 Sven Neumann 2007-05-28 13:08:32 UTC
Tobias, please do not change the version field to "Current SVN", at least not without adding a comment. It now looks as if this was a problem in SVN at the time you reported the bug. If you want to point out that a particular problem still exists, please add a comment for it.
Comment 8 tobias 2007-05-28 13:22:00 UTC
Sorry Sven, yes the problem still exists in the "Current SVN".
Comment 9 Michael Natterer 2012-01-08 21:51:24 UTC
Please try GIMP 2.7.4 and report back, we won't fix 2.6 bugs any longer.
Comment 10 Akhil Laddha 2012-02-21 12:37:27 UTC
Could you please try to reproduce bug with GIMP 2.7.4 or later version and update the bug report with your finding, tia.
Comment 11 tobias 2012-02-22 10:38:05 UTC
This bug is still in 2.7.4 (Windows).
Comment 12 Alexis Wilhelm 2012-06-17 18:48:18 UTC
Created attachment 216616 [details]

I redid the math to make sure there was no bug there. The problem happens with the inverse transform if one of the perspective's vanishing points is in the transformed region. Well, my calculations suggest that it should fail on the line that connects the vanishing points, but in practice it does not seem to be the case...

Anyway, I think we should just issue a warning if such a case happens, so that the user know why it failed. Or clip the result regardless of what the user says.

Also, comment 5 says that "clip" is on by default, but it seems that now the default option is "adjust". Is there a special reason for this change? If not we should use "clip" by default to prevent this bug from happening.

And bug 598985 describes the same problem.
Comment 13 Michael Natterer 2012-06-17 19:02:40 UTC
*** Bug 598985 has been marked as a duplicate of this bug. ***
Comment 14 Michael Natterer 2012-06-17 19:04:31 UTC
Adjust is the same as clip used to be, and transforming to huge sizes
is not really avoidable, maybe we need a maximum size here, it should
at least not crash.
Comment 15 Michael Natterer 2012-06-17 19:06:34 UTC
Err no, it's not the same :) Are you saying we should default to clip
if we inverse-transform?
Comment 16 Alexis Wilhelm 2012-06-17 21:00:14 UTC
Before I investigated this bug, I didn't even know there was a clip or adjust option, and I never noticed that parts of the transformed layer were outside the image, so yes, I wouldn't mind at all.

Well, "crop to result" might be a better default behavior. As I understand it, it crops if the result is larger than the image, and adjusts if it's smaller?
Comment 17 Massimo 2012-06-18 04:54:46 UTC
(In reply to comment #12)
> I redid the math to make sure there was no bug there. The problem happens with
> the inverse transform if one of the perspective's vanishing points is in the
> transformed region. Well, my calculations suggest that it should fail on the
> line that connects the vanishing points, but in practice it does not seem to be
> the case...

It fails when the horizon (the line connecting the vanishing points)
intersects the rectangle. In that case one or two corners are 
(mathematically) back  transformed from behind the viewer and the area
rendered includes parts from outside the source rectangle and does not
include part from inside (which is infinite).
Comment 18 Massimo 2012-06-18 16:39:38 UTC
Created attachment 216689 [details]

Attached a script that shows what happens when the horizon
intersects the source rectangle in the case of TRANSFORM-RESIZE-ADJUST

to be run from the command-line

gimp-2.8 -b '(load "perspective.scm")'

and replay the undo history to understand.

Basically the computation of the destination extent assumes that
the 4 transformed corners are directly connected, whereas two segments
connecting them are transformed to infinite lines passing through
the projective point at infinity.
Comment 19 Alexis Wilhelm 2012-06-20 05:45:11 UTC
Created attachment 216780 [details] [review]

This patch uses GIMP_TRANSFORM_RESIZE_CLIP when it detects that a transform will fail.

Unfortunately, it only works with 2.8. With current master it does nothing. It looks as if assigning clip_result inside gimp_drawable_transform_buffer_affine was ignored.
Comment 20 Alexis Wilhelm 2012-07-01 13:10:05 UTC
Created attachment 217766 [details] [review]
patch against gimp/master

The previous fix stopped working since the switch to GEGL in the transform tool (commit 8a7ea1c25a8e66b16f906595f6b08a6e6842c507).

The problem lies in gegl/operations/transform/transform-core.c. Although transform_generic() properly iterates over the destination buffer (so it only computes useful pixels when the result is clipped), gegl_transform_get_bounding_box() finds an incoherent bounding box, just as gimp_transform_resize_boundary() would if we did not set clip_result.

I added a boolean "result_clipped" property to the "gegl:transform" operation that is true when clip_result is GIMP_TRANSFORM_RESIZE_CLIP. Now gegl_transform_get_bounding_box() knows that we want to clip the result and acts accordingly.
Comment 21 Alexis Wilhelm 2012-07-01 13:10:43 UTC
Created attachment 217767 [details] [review]
patch against gegl/master
Comment 22 Jehan 2013-10-07 06:20:45 UTC

I was checking old bugs. I tried to follow the reproduction steps in the first comment against master, but could not see anything weird. I don't get an "empty image created", so I don't really see what was supposed to get wrong.

Anyone who participated to this bug by the past, and know what was wrong, has this bug outdated, and now it has been fixed in GIMP master?
Comment 23 tobias 2013-10-10 19:44:59 UTC
I've checked this bug with the latest GIT version of GIMP and GEGL and the bug is still there. Make sure that the transform direction is set to backward(corrective).
Comment 24 Michael Schumacher 2016-05-28 22:21:35 UTC
Yeah, confirming in current master as well. I'd say this is something we want to fix for 2.10.
Comment 25 Michael Natterer 2016-11-08 15:52:30 UTC
This fixes the GEGL part, only with a different patch:

commit 363b1c983be018c5fb344f1e482f1dbd0e6fe6a6
Author: Øyvind Kolås <>
Date:   Tue Nov 8 16:42:36 2016 +0100

    transform: add a clip-to-input property
    Add a property for GIMP to set when the used transformation matrix would
    make the size of the output explode. ref bug #316479

 operations/transform/transform-core.c | 19 +++++++++++++++++--
 operations/transform/transform-core.h |  1 +
 2 files changed, 18 insertions(+), 2 deletions(-)
Comment 26 Michael Natterer 2016-11-08 16:27:57 UTC
Fixed in master:

commit 768d06614f203bf555bbda1f6186d4730ae2f8b5
Author: Alexis Wilhelm <>
Date:   Tue Nov 8 17:15:16 2016 +0100

    Bug 316479 - The Perspective Tool creates an empy image...
    ...instead of transforming it
    Add gimp_matrix3_will_explode() which determines if a transform
    matrix will blow up something in a rectangle to infinity, and use
    the function so set both the GIMP and GEGL code paths to clip the
    transform to the input size.

 app/core/gimpdrawable-transform.c    |  4 ++++
 app/gegl/gimp-gegl-apply-operation.c |  9 +++++++--
 app/gegl/gimp-gegl-apply-operation.h |  1 +
 libgimpmath/gimpmath.def             |  1 +
 libgimpmath/gimpmatrix.c             | 36 ++++++++++++++++++++++++++++++++++++
 libgimpmath/gimpmatrix.h             |  6 ++++++
 6 files changed, 55 insertions(+), 2 deletions(-)