[gimp/gimp-2-8] Bug 680290: -90 degree rotation distortion of layer
- From: Massimo Valentini <mvalentini src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/gimp-2-8] Bug 680290: -90 degree rotation distortion of layer
- Date: Sat, 1 Jun 2013 15:07:58 +0000 (UTC)
commit ba98aedcb1f03b7307e22b20487d5cc9e7665f54
Author: Massimo Valentini <mvalentini src gnome org>
Date: Sat Jun 1 17:07:24 2013 +0200
Bug 680290: -90 degree rotation distortion of layer
The previous code did not consider that a transformation
described by a matrix with non integer values in the 3rd
column or by a non affine matrix requires interpolation
and make floating point arithmetic rounding errors
consistent with INTERPOLATION_NONE
app/core/gimp-transform-region.c | 9 +++++++--
libgimpmath/gimpmatrix.c | 38 ++++++++++++++++++++++----------------
2 files changed, 29 insertions(+), 18 deletions(-)
---
diff --git a/app/core/gimp-transform-region.c b/app/core/gimp-transform-region.c
index 87714c8..c289174 100644
--- a/app/core/gimp-transform-region.c
+++ b/app/core/gimp-transform-region.c
@@ -331,8 +331,13 @@ gimp_transform_region_nearest (TileManager *orig_tiles,
/* normalize homogeneous coords */
normalize_coords (1, &tu, &tv, &tw, &u, &v);
- iu = RINT (u);
- iv = RINT (v);
+ /* EPSILON here is useful to make floating point arithmetic
+ * rounding errors consistent when the exact computation
+ * results in a 'integer and a half'
+ */
+#define EPSILON 1.e-5
+ iu = floor (u + 0.5 + EPSILON);
+ iv = floor (v + 0.5 + EPSILON);
/* Set the destination pixels */
if (iu >= u1 && iu < u2 &&
diff --git a/libgimpmath/gimpmatrix.c b/libgimpmath/gimpmatrix.c
index 594cdd3..599c8bc 100644
--- a/libgimpmath/gimpmatrix.c
+++ b/libgimpmath/gimpmatrix.c
@@ -843,26 +843,32 @@ gimp_matrix3_is_affine (const GimpMatrix3 *matrix)
* Checks if we'll need to interpolate when applying this matrix as
* a transformation.
*
- * Returns: %TRUE if all entries of the upper left 2x2 matrix are
- * either 0 or 1, %FALSE otherwise
+ * Returns: %TRUE if the matrix is simple, %FALSE otherwise
*/
gboolean
gimp_matrix3_is_simple (const GimpMatrix3 *matrix)
{
- gdouble absm;
- gint i, j;
-
- for (i = 0; i < 2; i++)
- {
- for (j = 0; j < 2; j++)
- {
- absm = fabs (matrix->coeff[i][j]);
- if (absm > EPSILON && fabs (absm - 1.0) > EPSILON)
- return FALSE;
- }
- }
-
- return TRUE;
+ const gdouble (*c)[3] = matrix->coeff;
+
+#define approximately(a, b) (fabs ((a) - (b)) < EPSILON)
+#define integer(a) (approximately (a, RINT (a)))
+
+ /* 3rd row like identity matrix (perspective requires interpolation) */
+ return approximately (0.0, c[2][0] ) &&
+ approximately (0.0, c[2][1] ) &&
+ approximately (1.0, fabs (c[2][2])) &&
+ /* 3rd column integer (subpixel translation requires interpolation)*/
+ integer (c[0][2]) &&
+ integer (c[1][2]) &&
+ /* upper left 2x2 matrix [ 0, +-1; +-1, 0] or [+-1, 0; 0, +-1] */
+ ((approximately (0.0, c[0][0] ) &&
+ approximately (1.0, fabs (c[0][1])) &&
+ approximately (1.0, fabs (c[1][0])) &&
+ approximately (0.0, c[1][1] )) ||
+ (approximately (1.0, fabs (c[0][0])) &&
+ approximately (0.0, c[0][1] ) &&
+ approximately (0.0, c[1][0] ) &&
+ approximately (1.0, fabs (c[1][1]))));
}
/**
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]