[gimp] Bug 316479 - The Perspective Tool creates an empy image...
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] Bug 316479 - The Perspective Tool creates an empy image...
- Date: Tue, 8 Nov 2016 16:26:53 +0000 (UTC)
commit 768d06614f203bf555bbda1f6186d4730ae2f8b5
Author: Alexis Wilhelm <alexiswilhelm%40gmail.com>
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(-)
---
diff --git a/app/core/gimpdrawable-transform.c b/app/core/gimpdrawable-transform.c
index a4baa00..034603a 100644
--- a/app/core/gimpdrawable-transform.c
+++ b/app/core/gimpdrawable-transform.c
@@ -116,6 +116,9 @@ gimp_drawable_transform_buffer_affine (GimpDrawable *drawable,
! babl_format_has_alpha (gegl_buffer_get_format (orig_buffer)))
clip_result = GIMP_TRANSFORM_RESIZE_CLIP;
+ if (gimp_matrix3_will_explode (&m, u1, v1, u2, v2))
+ clip_result = GIMP_TRANSFORM_RESIZE_CLIP;
+
/* Find the bounding coordinates of target */
gimp_transform_resize_boundary (&m, clip_result,
u1, v1, u2, v2,
@@ -133,6 +136,7 @@ gimp_drawable_transform_buffer_affine (GimpDrawable *drawable,
gimp_gegl_apply_transform (orig_buffer, progress, NULL,
new_buffer,
interpolation_type,
+ clip_result,
&gegl_matrix);
*new_offset_x = x1;
diff --git a/app/gegl/gimp-gegl-apply-operation.c b/app/gegl/gimp-gegl-apply-operation.c
index a86e2de..41440d7 100644
--- a/app/gegl/gimp-gegl-apply-operation.c
+++ b/app/gegl/gimp-gegl-apply-operation.c
@@ -685,17 +685,22 @@ gimp_gegl_apply_transform (GeglBuffer *src_buffer,
const gchar *undo_desc,
GeglBuffer *dest_buffer,
GimpInterpolationType interpolation_type,
+ GimpTransformResize clip_result,
GimpMatrix3 *transform)
{
GeglNode *node;
+ gboolean clip_to_input;
g_return_if_fail (GEGL_IS_BUFFER (src_buffer));
g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress));
g_return_if_fail (GEGL_IS_BUFFER (dest_buffer));
+ clip_to_input = (clip_result == GIMP_TRANSFORM_RESIZE_CLIP);
+
node = gegl_node_new_child (NULL,
- "operation", "gegl:transform",
- "sampler", interpolation_type,
+ "operation", "gegl:transform",
+ "sampler", interpolation_type,
+ "clip-to-input", clip_to_input,
NULL);
gimp_gegl_node_set_matrix (node, transform);
diff --git a/app/gegl/gimp-gegl-apply-operation.h b/app/gegl/gimp-gegl-apply-operation.h
index acca14b..9039b5b 100644
--- a/app/gegl/gimp-gegl-apply-operation.h
+++ b/app/gegl/gimp-gegl-apply-operation.h
@@ -153,6 +153,7 @@ void gimp_gegl_apply_transform (GeglBuffer *src_buffer,
const gchar *undo_desc,
GeglBuffer *dest_buffer,
GimpInterpolationType interpolation_type,
+ GimpTransformResize clip_result,
GimpMatrix3 *transform);
diff --git a/libgimpmath/gimpmath.def b/libgimpmath/gimpmath.def
index 1a48940..039a03d 100644
--- a/libgimpmath/gimpmath.def
+++ b/libgimpmath/gimpmath.def
@@ -16,6 +16,7 @@ EXPORTS
gimp_matrix3_scale
gimp_matrix3_transform_point
gimp_matrix3_translate
+ gimp_matrix3_will_explode
gimp_matrix3_xshear
gimp_matrix3_yshear
gimp_matrix4_to_deg
diff --git a/libgimpmath/gimpmatrix.c b/libgimpmath/gimpmatrix.c
index 48c2210..457057d 100644
--- a/libgimpmath/gimpmatrix.c
+++ b/libgimpmath/gimpmatrix.c
@@ -866,6 +866,42 @@ gimp_matrix3_is_simple (const GimpMatrix3 *matrix)
}
/**
+ * gimp_matrix3_will_explode:
+ * @m: The matrix that is to be tested.
+ * @u1: The rectangle's left coordinate.
+ * @v1: The rectangle's top coordinate.
+ * @u2: The rectangle's right coordinate.
+ * @v2: The rectangle's bottom coordinate.
+ *
+ * Checks if the given transformation maps a point of the rectangle to
+ * infinity, or something equally stupid.
+ *
+ * Returns: %TRUE if the transformation will fail, %FALSE otherwise
+ *
+ * Since: 2.10
+ */
+gboolean
+gimp_matrix3_will_explode (const GimpMatrix3 *m,
+ gdouble u1,
+ gdouble v1,
+ gdouble u2,
+ gdouble v2)
+{
+ const gdouble a = m->coeff[2][0];
+ const gdouble b = m->coeff[2][1];
+ const gdouble c = m->coeff[2][2];
+ const gdouble d1 = a * u1 + b * v1 + c;
+ const gdouble d2 = a * u1 + b * v2 + c;
+ const gdouble d3 = a * u2 + b * v1 + c;
+ const gdouble d4 = a * u2 + b * v2 + c;
+
+ /* We are safe if all 4 corners of the region are on the same side
+ * of the a.u+b.v+c=0 line, ie. if d1..d4 have the same sign.
+ */
+ return ! (d1 * d2 > 0 && d1 * d3 > 0 && d1 * d4 > 0);
+}
+
+/**
* gimp_matrix4_to_deg:
* @matrix:
* @a:
diff --git a/libgimpmath/gimpmatrix.h b/libgimpmath/gimpmatrix.h
index e435d88..23a7587 100644
--- a/libgimpmath/gimpmatrix.h
+++ b/libgimpmath/gimpmatrix.h
@@ -111,6 +111,12 @@ gboolean gimp_matrix3_is_diagonal (const GimpMatrix3 *matrix);
gboolean gimp_matrix3_is_affine (const GimpMatrix3 *matrix);
gboolean gimp_matrix3_is_simple (const GimpMatrix3 *matrix);
+gboolean gimp_matrix3_will_explode (const GimpMatrix3 *matrix,
+ gdouble u1,
+ gdouble v1,
+ gdouble u2,
+ gdouble v2);
+
void gimp_matrix3_transform_point (const GimpMatrix3 *matrix,
gdouble x,
gdouble y,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]