[gegl] operations: Add scale-size-keepaspect



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]