[gegl] operations: Add scale-size-keepaspect
- From: Jon Nordby <jonnor src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] operations: Add scale-size-keepaspect
- Date: Mon, 5 Jan 2015 17:47:42 +0000 (UTC)
commit 24b8b092cdc17634c24eb76fd191c954ee625a88
Author: Jon Nordby <jononor gmail com>
Date: Mon Jan 5 16:14:09 2015 +0100
operations: Add scale-size-keepaspect
The original scale-size requires to pass both height and width.
scale-size-keepaspect will calculate one from the other, preserving
the original aspect ratio if only one is specified.
If no dimensions are specified, keeps original dimensions.
operations/transform/Makefile.am | 1 +
operations/transform/module.c | 2 +
operations/transform/scale-size-keepaspect.c | 79 ++++++++++++++++++++++++++
3 files changed, 82 insertions(+), 0 deletions(-)
---
diff --git a/operations/transform/Makefile.am b/operations/transform/Makefile.am
index ec7d2ef..30d8f1e 100644
--- a/operations/transform/Makefile.am
+++ b/operations/transform/Makefile.am
@@ -15,6 +15,7 @@ transformops_la_SOURCES = \
rotate.c \
scale-ratio.c \
scale-size.c \
+ scale-size-keepaspect.c \
shear.c \
transform.c \
translate.c \
diff --git a/operations/transform/module.c b/operations/transform/module.c
index c9dae5a..5148dfa 100644
--- a/operations/transform/module.c
+++ b/operations/transform/module.c
@@ -42,6 +42,7 @@ gegl_module_query (GTypeModule *module)
GType rotate_get_type (void);
GType scale_ratio_get_type (void);
GType scale_size_get_type (void);
+GType scale_size_keepaspect_get_type (void);
GType shear_get_type (void);
GType translate_get_type (void);
GType reflect_get_type (void);
@@ -57,6 +58,7 @@ gegl_module_register (GTypeModule *module)
dummy = rotate_get_type ();
dummy = scale_ratio_get_type ();
dummy = scale_size_get_type ();
+ dummy = scale_size_keepaspect_get_type ();
dummy = shear_get_type ();
dummy = translate_get_type ();
dummy = reflect_get_type ();
diff --git a/operations/transform/scale-size-keepaspect.c b/operations/transform/scale-size-keepaspect.c
new file mode 100644
index 0000000..5f6cbf4
--- /dev/null
+++ b/operations/transform/scale-size-keepaspect.c
@@ -0,0 +1,79 @@
+/* This file is part of GEGL
+ *
+ * GEGL is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * GEGL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GEGL; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright 2014 Jon Nordby, The Grid <jononor gmail com>
+ */
+
+#include "config.h"
+#include <glib/gi18n-lib.h>
+
+#ifdef GEGL_CHANT_PROPERTIES
+
+gegl_chant_double (x, -G_MAXDOUBLE, G_MAXDOUBLE, -1.0,
+ _("Horizontal size"))
+gegl_chant_double (y, -G_MAXDOUBLE, G_MAXDOUBLE, -1.0,
+ _("Vertical size"))
+
+#else
+
+#define GEGL_CHANT_NAME scale_size_keepaspect
+#define GEGL_CHANT_OPERATION_NAME "gegl:scale-size-keepaspect"
+#define GEGL_CHANT_DESCRIPTION _("Scales the buffer to a size, preserving aspect ratio")
+#define GEGL_CHANT_SELF "scale-size-keepaspect.c"
+#include "chant.h"
+
+#include <math.h>
+
+static void
+create_matrix (OpTransform *op,
+ GeglMatrix3 *matrix)
+{
+ GeglChantOperation *chant = GEGL_CHANT_OPERATION (op);
+ GeglOperation *operation = GEGL_OPERATION (op);
+ GeglRectangle in_rect = {0,0,0,0};
+ gdouble height_over_width = 1.0;
+
+ if (gegl_operation_source_get_bounding_box (operation, "input"))
+ in_rect = *gegl_operation_source_get_bounding_box (operation, "input");
+
+ // Avoid divide-by-zero
+ if(in_rect.width < 1)
+ in_rect.width = 1;
+ if(in_rect.height < 1)
+ in_rect.height = 1;
+
+ height_over_width = in_rect.height/(gdouble)in_rect.width;
+ if (chant->x <= 0.0 && chant->y <= 0.0) {
+ // No dimensions specified, pass through
+ matrix->coeff [0][0] = 1.0;
+ matrix->coeff [1][1] = 1.0;
+ } else if (chant->x <= 0.0 && chant->y > 0.0) {
+ // X free, Y specified
+ const gdouble target_x = chant->y / height_over_width;
+ matrix->coeff [0][0] = target_x / (gdouble) in_rect.width;
+ matrix->coeff [1][1] = chant->y / (gdouble) in_rect.height;
+ } else if (chant->y <= 0.0 && chant->x > 0.0) {
+ // Y free, X specified
+ const gdouble target_y = chant->x * height_over_width;
+ matrix->coeff [0][0] = chant->x / (gdouble) in_rect.width;
+ matrix->coeff [1][1] = target_y / (gdouble) in_rect.height;
+ } else {
+ // Fully specified
+ matrix->coeff [0][0] = chant->x / (gdouble) in_rect.width;
+ matrix->coeff [1][1] = chant->y / (gdouble) in_rect.height;
+ }
+}
+
+#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]