From 0a6d8a2f4bc87fbfe27f0ab4f79c8a81b0c4b2e3 Mon Sep 17 00:00:00 2001 From: MEST 1999 Sven Neumann Date: Fri, 9 Jul 1999 14:51:01 +0000 Subject: [PATCH] added a few functions to test for matrix properties Fri Jul 9 16:47:04 MEST 1999 Sven Neumann * libgimp/gimpmatrix.[ch]: added a few functions to test for matrix properties * app/transform_core.c: if we are doing a simple transformation (e.g. rotating by 90 degrees), turn off interpolation * app/rotate_tool.c: persuade the slider that a rotate angle of 180 degrees is perfectly ok --Sven --- ChangeLog | 11 ++++++ app/rotate_tool.c | 3 +- app/tools/gimprotatetool.c | 3 +- app/tools/rotate_tool.c | 3 +- app/tools/transform_core.c | 7 +++- app/transform_core.c | 7 +++- libgimp/gimpmatrix.c | 76 +++++++++++++++++++++++++++++++++++++- libgimp/gimpmatrix.h | 10 +++++ 8 files changed, 113 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index e0d075449a..7a4d028988 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +Fri Jul 9 16:47:04 MEST 1999 Sven Neumann + + * libgimp/gimpmatrix.[ch]: added a few functions to test for + matrix properties + + * app/transform_core.c: if we are doing a simple transformation + (e.g. rotating by 90 degrees), turn off interpolation + + * app/rotate_tool.c: persuade the slider that a rotate angle of + 180 degrees is perfectly ok + 1999-07-09 Michael Natterer * app/crop.c: mysteriously, using the new tool constructor fixed diff --git a/app/rotate_tool.c b/app/rotate_tool.c index 006b732c73..8216273808 100644 --- a/app/rotate_tool.c +++ b/app/rotate_tool.c @@ -95,8 +95,9 @@ rotate_tool_transform (Tool *tool, tool); gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (widget), TRUE); + /* this looks strange (-180, 181), but it works */ widget = info_dialog_add_scale (transform_info, "", &angle_val, - -180, 180, 0.01, 0.1, 1, -1, + -180, 181, 0.01, 0.1, 1, -1, (GtkSignalFunc) rotate_angle_changed, tool); gtk_widget_set_usize (widget, 180, 0); diff --git a/app/tools/gimprotatetool.c b/app/tools/gimprotatetool.c index 006b732c73..8216273808 100644 --- a/app/tools/gimprotatetool.c +++ b/app/tools/gimprotatetool.c @@ -95,8 +95,9 @@ rotate_tool_transform (Tool *tool, tool); gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (widget), TRUE); + /* this looks strange (-180, 181), but it works */ widget = info_dialog_add_scale (transform_info, "", &angle_val, - -180, 180, 0.01, 0.1, 1, -1, + -180, 181, 0.01, 0.1, 1, -1, (GtkSignalFunc) rotate_angle_changed, tool); gtk_widget_set_usize (widget, 180, 0); diff --git a/app/tools/rotate_tool.c b/app/tools/rotate_tool.c index 006b732c73..8216273808 100644 --- a/app/tools/rotate_tool.c +++ b/app/tools/rotate_tool.c @@ -95,8 +95,9 @@ rotate_tool_transform (Tool *tool, tool); gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (widget), TRUE); + /* this looks strange (-180, 181), but it works */ widget = info_dialog_add_scale (transform_info, "", &angle_val, - -180, 180, 0.01, 0.1, 1, -1, + -180, 181, 0.01, 0.1, 1, -1, (GtkSignalFunc) rotate_angle_changed, tool); gtk_widget_set_usize (widget, 180, 0); diff --git a/app/tools/transform_core.c b/app/tools/transform_core.c index 7ef9e9f368..1bf4838335 100644 --- a/app/tools/transform_core.c +++ b/app/tools/transform_core.c @@ -1026,6 +1026,10 @@ transform_core_do (GImage *gimage, int newval; alpha = 0; + + /* turn interpolation off for simple transformations (e.g. rot90) */ + if (gimp_matrix_is_simple (matrix)) + interpolation = FALSE; /* Get the background color */ gimage_get_background (gimage, drawable, bg_col); @@ -1062,7 +1066,7 @@ transform_core_do (GImage *gimage, gimp_matrix_invert (matrix, m); } - paths_transform_current_path(gimage,matrix,FALSE); + paths_transform_current_path (gimage, matrix, FALSE); x1 = float_tiles->x; y1 = float_tiles->y; @@ -1128,6 +1132,7 @@ transform_core_do (GImage *gimage, ty = yinc * (tx1 + 0.5) + m[1][1] * (y + 0.5) + m[1][2]; tw = winc * (tx1 + 0.5) + m[2][1] * (y + 0.5) + m[2][2]; d = dest; + for (x = tx1; x < tx2; x++) { /* normalize homogeneous coords */ diff --git a/app/transform_core.c b/app/transform_core.c index 7ef9e9f368..1bf4838335 100644 --- a/app/transform_core.c +++ b/app/transform_core.c @@ -1026,6 +1026,10 @@ transform_core_do (GImage *gimage, int newval; alpha = 0; + + /* turn interpolation off for simple transformations (e.g. rot90) */ + if (gimp_matrix_is_simple (matrix)) + interpolation = FALSE; /* Get the background color */ gimage_get_background (gimage, drawable, bg_col); @@ -1062,7 +1066,7 @@ transform_core_do (GImage *gimage, gimp_matrix_invert (matrix, m); } - paths_transform_current_path(gimage,matrix,FALSE); + paths_transform_current_path (gimage, matrix, FALSE); x1 = float_tiles->x; y1 = float_tiles->y; @@ -1128,6 +1132,7 @@ transform_core_do (GImage *gimage, ty = yinc * (tx1 + 0.5) + m[1][1] * (y + 0.5) + m[1][2]; tw = winc * (tx1 + 0.5) + m[2][1] * (y + 0.5) + m[2][2]; d = dest; + for (x = tx1; x < tx2; x++) { /* normalize homogeneous coords */ diff --git a/libgimp/gimpmatrix.c b/libgimp/gimpmatrix.c index bd31a79e29..19d335f7ac 100644 --- a/libgimp/gimpmatrix.c +++ b/libgimp/gimpmatrix.c @@ -17,9 +17,12 @@ * Boston, MA 02111-1307, USA. */ -#include "gimpmatrix.h" +#include #include #include +#include "gimpmatrix.h" + +#define EPSILON 1e-6 void gimp_matrix_transform_point (GimpMatrix m, double x, double y, @@ -175,5 +178,74 @@ gimp_matrix_invert (GimpMatrix m, GimpMatrix m_inv) void gimp_matrix_duplicate (GimpMatrix src, GimpMatrix target) { - memcpy(&target[0][0], &src[0][0], sizeof(GimpMatrix)); + memcpy (&target[0][0], &src[0][0], sizeof(GimpMatrix)); } + + +/* functions to test for matrix properties */ + +int +gimp_matrix_is_diagonal (GimpMatrix m) +{ + int i,j; + + for (i = 0; i < 3; i++) + { + for (j = 0; j < 3; j++) + { + if (i != j && fabs (m[i][j]) > EPSILON) + return FALSE; + } + } + return TRUE; +} + +int +gimp_matrix_is_identity (GimpMatrix m) +{ + int i,j; + + for (i = 0; i < 3; i++) + { + for (j = 0; j < 3; j++) + { + if (i == j) + { + if (fabs (m[i][j] - 1.0) > EPSILON) + return FALSE; + } + else + { + if (fabs (m[i][j]) > EPSILON) + return FALSE; + } + } + } + return TRUE; +} + +/* Check if we'll need to interpolate when applying this matrix. + This function returns TRUE if all entries of the upper left + 2x2 matrix are either 0 or 1 + */ +int +gimp_matrix_is_simple (GimpMatrix m) +{ + double absm; + int i,j; + + for (i = 0; i < 2; i++) + { + for (j = 0; j < 2; j++) + { + absm = fabs (m[i][j]); + if (absm > EPSILON && fabs (absm - 1.0) > EPSILON) + return FALSE; + } + } + return TRUE; +} + + + + diff --git a/libgimp/gimpmatrix.h b/libgimp/gimpmatrix.h index e9cf9964ed..38a9547dcc 100644 --- a/libgimp/gimpmatrix.h +++ b/libgimp/gimpmatrix.h @@ -38,9 +38,19 @@ void gimp_matrix_yshear (GimpMatrix, double); double gimp_matrix_determinant (GimpMatrix); void gimp_matrix_invert (GimpMatrix m, GimpMatrix m_inv); void gimp_matrix_duplicate (GimpMatrix src, GimpMatrix target); +int gimp_matrix_is_diagonal (GimpMatrix m); +int gimp_matrix_is_identity (GimpMatrix m); +int gimp_matrix_is_simple (GimpMatrix m); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* __GIMPMATRIX_H__ */ + + + + + + +