diff options
author | Thiago Santos <thiago.sousa.santos@collabora.co.uk> | 2010-06-02 00:34:36 -0300 |
---|---|---|
committer | Thiago Santos <thiago.sousa.santos@collabora.co.uk> | 2010-06-04 15:31:20 -0300 |
commit | 2f9a630a6293e6e6ae5244c5c148f712520981ce (patch) | |
tree | 62095b668df2e8ea1427770ca7ad9671bb3f8030 /gst/geometrictransform | |
parent | dcda4b606c83a3af14668f073e9dcf2766eee558 (diff) | |
download | gstreamer-plugins-bad-2f9a630a6293e6e6ae5244c5c148f712520981ce.tar.gz |
geometrictransform: Adds a intermediary baseclass circlegeometrictransform
Adds an intermediary baseclass named gstcirclegeometrictransform
to keep common properties code for filters that operate on
a circular area.
Diffstat (limited to 'gst/geometrictransform')
-rw-r--r-- | gst/geometrictransform/Makefile.am | 5 | ||||
-rw-r--r-- | gst/geometrictransform/gstcirclegeometrictransform.c | 225 | ||||
-rw-r--r-- | gst/geometrictransform/gstcirclegeometrictransform.h | 93 | ||||
-rw-r--r-- | gst/geometrictransform/gstpinch.c | 82 | ||||
-rw-r--r-- | gst/geometrictransform/gstpinch.h | 12 |
5 files changed, 337 insertions, 80 deletions
diff --git a/gst/geometrictransform/Makefile.am b/gst/geometrictransform/Makefile.am index 849dea2d3..683097700 100644 --- a/gst/geometrictransform/Makefile.am +++ b/gst/geometrictransform/Makefile.am @@ -2,6 +2,7 @@ plugin_LTLIBRARIES = libgstgeometrictransform.la libgstgeometrictransform_la_SOURCES = plugin.c \ gstgeometrictransform.c \ + gstcirclegeometrictransform.c \ gstpinch.c libgstgeometrictransform_la_CFLAGS = $(GST_CFLAGS) $(GST_BASE_CFLAGS) \ @@ -10,4 +11,6 @@ libgstgeometrictransform_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) -lgstvideo-@GST_MA libgstgeometrictransform_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstgeometrictransform_la_LIBTOOLFLAGS = --tag=disable-static -noinst_HEADERS = gstgeometrictransform.h gstpinch.h +noinst_HEADERS = gstgeometrictransform.h \ + gstcirclegeometrictransform.h \ + gstpinch.h diff --git a/gst/geometrictransform/gstcirclegeometrictransform.c b/gst/geometrictransform/gstcirclegeometrictransform.c new file mode 100644 index 000000000..dfc10bc28 --- /dev/null +++ b/gst/geometrictransform/gstcirclegeometrictransform.c @@ -0,0 +1,225 @@ +/* + * GStreamer + * Copyright (C) 2010 Thiago Santos <thiago.sousa.santos@collabora.co.uk> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Alternatively, the contents of this file may be used under the + * GNU Lesser General Public License Version 2.1 (the "LGPL"), in + * which case the following provisions apply instead of the ones + * mentioned above: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Thanks to Jerry Huxtable <http://www.jhlabs.com> work on its java + * image editor and filters. The algorithms here were extracted from + * his code. + */ + + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <gst/gst.h> +#include <math.h> + +#include "gstcirclegeometrictransform.h" + +GST_DEBUG_CATEGORY_STATIC (gst_circle_geometric_transform_debug); +#define GST_CAT_DEFAULT gst_circle_geometric_transform_debug + +GstGeometricTransformClass *parent_class; + +enum +{ + PROP_0, + PROP_X_CENTER, + PROP_Y_CENTER, + PROP_RADIUS +}; + +#define DEFAULT_X_CENTER 0.5 +#define DEFAULT_Y_CENTER 0.5 +#define DEFAULT_RADIUS 100 + +static void +gst_circle_geometric_transform_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstCircleGeometricTransform *circle_geometric_transform; + + circle_geometric_transform = GST_CIRCLE_GEOMETRIC_TRANSFORM_CAST (object); + + switch (prop_id) { + case PROP_X_CENTER: + circle_geometric_transform->x_center = g_value_get_double (value); + break; + case PROP_Y_CENTER: + circle_geometric_transform->y_center = g_value_get_double (value); + break; + case PROP_RADIUS: + circle_geometric_transform->radius = g_value_get_double (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_circle_geometric_transform_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstCircleGeometricTransform *circle_geometric_transform; + + circle_geometric_transform = GST_CIRCLE_GEOMETRIC_TRANSFORM_CAST (object); + + switch (prop_id) { + case PROP_X_CENTER: + g_value_set_double (value, circle_geometric_transform->x_center); + break; + case PROP_Y_CENTER: + g_value_set_double (value, circle_geometric_transform->y_center); + break; + case PROP_RADIUS: + g_value_set_double (value, circle_geometric_transform->radius); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +/* Clean up */ +static void +gst_circle_geometric_transform_finalize (GObject * obj) +{ + G_OBJECT_CLASS (parent_class)->finalize (obj); +} + +/* GObject vmethod implementations */ + +static gboolean +circle_geometric_transform_precalc (GstGeometricTransform * gt) +{ + GstCircleGeometricTransform *cgt = GST_CIRCLE_GEOMETRIC_TRANSFORM_CAST (gt); + + cgt->precalc_x_center = cgt->x_center * gt->width; + cgt->precalc_y_center = cgt->y_center * gt->height; + cgt->precalc_radius2 = cgt->radius * cgt->radius; + + return TRUE; +} + +static void +gst_circle_geometric_transform_class_init (GstCircleGeometricTransformClass * + klass) +{ + GObjectClass *gobject_class; + GstGeometricTransformClass *gstgt_class; + + gobject_class = (GObjectClass *) klass; + gstgt_class = (GstGeometricTransformClass *) klass; + + parent_class = g_type_class_peek_parent (klass); + + gobject_class->finalize = + GST_DEBUG_FUNCPTR (gst_circle_geometric_transform_finalize); + gobject_class->set_property = + GST_DEBUG_FUNCPTR (gst_circle_geometric_transform_set_property); + gobject_class->get_property = + GST_DEBUG_FUNCPTR (gst_circle_geometric_transform_get_property); + + + /* FIXME I don't like the idea of x-center and y-center being in % and + * radius and intensity in absolute values, I think no one likes it, but + * I can't see a way to have nice default values without % */ + g_object_class_install_property (gobject_class, PROP_X_CENTER, + g_param_spec_double ("x-center", "x center", + "X axis center of the circle_geometric_transform effect", + 0.0, 1.0, DEFAULT_X_CENTER, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_Y_CENTER, + g_param_spec_double ("y-center", "y center", + "Y axis center of the circle_geometric_transform effect", + 0.0, 1.0, DEFAULT_Y_CENTER, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_RADIUS, + g_param_spec_double ("radius", "radius", + "radius of the circle_geometric_transform effect", 0.0, G_MAXDOUBLE, + DEFAULT_RADIUS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + gstgt_class->prepare_func = circle_geometric_transform_precalc; +} + +static void +gst_circle_geometric_transform_init (GstCircleGeometricTransform * filter, + GstCircleGeometricTransformClass * gclass) +{ + filter->x_center = DEFAULT_X_CENTER; + filter->y_center = DEFAULT_Y_CENTER; + filter->radius = DEFAULT_RADIUS; +} + +GType +gst_circle_geometric_transform_get_type (void) +{ + static GType circle_geometric_transform_type = 0; + + if (!circle_geometric_transform_type) { + static const GTypeInfo circle_geometric_transform_info = { + sizeof (GstCircleGeometricTransformClass), + NULL, + NULL, + (GClassInitFunc) gst_circle_geometric_transform_class_init, + NULL, + NULL, + sizeof (GstCircleGeometricTransform), + 0, + (GInstanceInitFunc) gst_circle_geometric_transform_init, + }; + + circle_geometric_transform_type = + g_type_register_static (GST_TYPE_GEOMETRIC_TRANSFORM, + "GstCircleGeometricTransform", &circle_geometric_transform_info, + G_TYPE_FLAG_ABSTRACT); + + GST_DEBUG_CATEGORY_INIT (gst_circle_geometric_transform_debug, + "circlegeometrictransform", 0, + "Base class for geometric transform elements that operate " + "on a circular area"); + } + return circle_geometric_transform_type; +} diff --git a/gst/geometrictransform/gstcirclegeometrictransform.h b/gst/geometrictransform/gstcirclegeometrictransform.h new file mode 100644 index 000000000..fafdf931b --- /dev/null +++ b/gst/geometrictransform/gstcirclegeometrictransform.h @@ -0,0 +1,93 @@ +/* + * GStreamer + * Copyright (C) 2010 Thiago Santos <thiago.sousa.santos@collabora.co.uk> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Alternatively, the contents of this file may be used under the + * GNU Lesser General Public License Version 2.1 (the "LGPL"), in + * which case the following provisions apply instead of the ones + * mentioned above: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_CIRCLE_GEOMETRIC_TRANSFORM_H__ +#define __GST_CIRCLE_GEOMETRIC_TRANSFORM_H__ + +#include <gst/gst.h> +#include "gstgeometrictransform.h" + +G_BEGIN_DECLS + +/* #defines don't like whitespacey bits */ +#define GST_TYPE_CIRCLE_GEOMETRIC_TRANSFORM \ + (gst_circle_geometric_transform_get_type()) +#define GST_CIRCLE_GEOMETRIC_TRANSFORM(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_CIRCLE_GEOMETRIC_TRANSFORM,GstCircleGeometricTransform)) +#define GST_CIRCLE_GEOMETRIC_TRANSFORM_CAST(obj) \ + ((GstCircleGeometricTransform *)(obj)) +#define GST_CIRCLE_GEOMETRIC_TRANSFORM_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_CIRCLE_GEOMETRIC_TRANSFORM,GstCircleGeometricTransformClass)) +#define GST_IS_CIRCLE_GEOMETRIC_TRANSFORM(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_CIRCLE_GEOMETRIC_TRANSFORM)) +#define GST_IS_CIRCLE_GEOMETRIC_TRANSFORM_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_CIRCLE_GEOMETRIC_TRANSFORM)) + +typedef struct _GstCircleGeometricTransform GstCircleGeometricTransform; +typedef struct _GstCircleGeometricTransformClass GstCircleGeometricTransformClass; + +struct _GstCircleGeometricTransform +{ + GstGeometricTransform element; + + gdouble x_center; + gdouble y_center; + gdouble radius; + + gdouble precalc_x_center; + gdouble precalc_y_center; + gdouble precalc_radius2; +}; + +struct _GstCircleGeometricTransformClass +{ + GstGeometricTransformClass parent_class; +}; + +GType gst_circle_geometric_transform_get_type (void); + +gboolean gst_circle_geometric_transform_plugin_init (GstPlugin * plugin); + +G_END_DECLS + +#endif /* __GST_CIRCLE_GEOMETRIC_TRANSFORM_H__ */ diff --git a/gst/geometrictransform/gstpinch.c b/gst/geometrictransform/gstpinch.c index 13be3b342..bb0dd4008 100644 --- a/gst/geometrictransform/gstpinch.c +++ b/gst/geometrictransform/gstpinch.c @@ -63,19 +63,13 @@ GST_DEBUG_CATEGORY_STATIC (gst_pinch_debug); enum { PROP_0, - PROP_X_CENTER, - PROP_Y_CENTER, - PROP_RADIUS, PROP_INTENSITY }; -#define DEFAULT_X_CENTER 0.5 -#define DEFAULT_Y_CENTER 0.5 -#define DEFAULT_RADIUS 100 #define DEFAULT_INTENSITY 0.5 -GST_BOILERPLATE (GstPinch, gst_pinch, GstGeometricTransform, - GST_TYPE_GEOMETRIC_TRANSFORM); +GST_BOILERPLATE (GstPinch, gst_pinch, GstCircleGeometricTransform, + GST_TYPE_CIRCLE_GEOMETRIC_TRANSFORM); static void gst_pinch_set_property (GObject * object, guint prop_id, const GValue * value, @@ -86,15 +80,6 @@ gst_pinch_set_property (GObject * object, guint prop_id, const GValue * value, pinch = GST_PINCH_CAST (object); switch (prop_id) { - case PROP_X_CENTER: - pinch->x_center = g_value_get_double (value); - break; - case PROP_Y_CENTER: - pinch->y_center = g_value_get_double (value); - break; - case PROP_RADIUS: - pinch->radius = g_value_get_double (value); - break; case PROP_INTENSITY: pinch->intensity = g_value_get_double (value); break; @@ -113,15 +98,6 @@ gst_pinch_get_property (GObject * object, guint prop_id, pinch = GST_PINCH_CAST (object); switch (prop_id) { - case PROP_X_CENTER: - g_value_set_double (value, pinch->x_center); - break; - case PROP_Y_CENTER: - g_value_set_double (value, pinch->y_center); - break; - case PROP_RADIUS: - g_value_set_double (value, pinch->radius); - break; case PROP_INTENSITY: g_value_set_double (value, pinch->intensity); break; @@ -153,42 +129,29 @@ gst_pinch_base_init (gpointer gclass) } static gboolean -pinch_precalc (GstGeometricTransform * gt) -{ - GstPinch *pinch = GST_PINCH_CAST (gt); - - pinch->precalc_x_center = pinch->x_center * gt->width; - pinch->precalc_y_center = pinch->y_center * gt->height; - - return TRUE; -} - -static gboolean pinch_map (GstGeometricTransform * gt, gint x, gint y, gdouble * in_x, gdouble * in_y) { + GstCircleGeometricTransform *cgt = GST_CIRCLE_GEOMETRIC_TRANSFORM_CAST (gt); GstPinch *pinch = GST_PINCH_CAST (gt); - gdouble r2; gdouble distance; gdouble dx, dy; - dx = x - pinch->precalc_x_center; - dy = y - pinch->precalc_y_center; + dx = x - cgt->precalc_x_center; + dy = y - cgt->precalc_y_center; distance = dx * dx + dy * dy; - r2 = pinch->radius * pinch->radius; - GST_LOG_OBJECT (pinch, "Center %0.5lf (%0.2lf) %0.5lf (%0.2lf)", - pinch->precalc_x_center, pinch->x_center, pinch->precalc_y_center, - pinch->y_center); + cgt->precalc_x_center, cgt->x_center, cgt->precalc_y_center, + cgt->y_center); GST_LOG_OBJECT (pinch, "Input %d %d, distance=%lf, radius2=%lf, dx=%lf" - ", dy=%lf", x, y, distance, r2, dx, dy); + ", dy=%lf", x, y, distance, cgt->precalc_radius2, dx, dy); - if (distance > r2 || distance == 0) { + if (distance > cgt->precalc_radius2 || distance == 0) { *in_x = x; *in_y = y; } else { - gdouble d = sqrt (distance / r2); + gdouble d = sqrt (distance / cgt->precalc_radius2); gdouble t = pow (sin (G_PI * 0.5 * d), -pinch->intensity); dx *= t; @@ -196,8 +159,8 @@ pinch_map (GstGeometricTransform * gt, gint x, gint y, gdouble * in_x, GST_LOG_OBJECT (pinch, "D=%lf, t=%lf, dx=%lf" ", dy=%lf", d, t, dx, dy); - *in_x = pinch->precalc_x_center + dx; - *in_y = pinch->precalc_y_center + dy; + *in_x = cgt->precalc_x_center + dx; + *in_y = cgt->precalc_y_center + dy; *in_x = CLAMP (*in_x, 0, gt->width - 1); *in_y = CLAMP (*in_y, 0, gt->height - 1); @@ -225,23 +188,6 @@ gst_pinch_class_init (GstPinchClass * klass) gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_pinch_get_property); - /* FIXME I don't like the idea of x-center and y-center being in % and - * radius and intensity in absolute values, I think no one likes it, but - * I can't see a way to have nice default values without % */ - g_object_class_install_property (gobject_class, PROP_X_CENTER, - g_param_spec_double ("x-center", "x center", - "X axis center of the pinch effect", - 0.0, 1.0, DEFAULT_X_CENTER, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_Y_CENTER, - g_param_spec_double ("y-center", "y center", - "Y axis center of the pinch effect", - 0.0, 1.0, DEFAULT_Y_CENTER, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_RADIUS, - g_param_spec_double ("radius", "radius", "radius of the pinch effect", - 0.0, G_MAXDOUBLE, DEFAULT_RADIUS, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class, PROP_INTENSITY, g_param_spec_double ("intensity", "intensity", "intensity of the pinch effect", @@ -249,16 +195,12 @@ gst_pinch_class_init (GstPinchClass * klass) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); gstgt_class->map_func = pinch_map; - gstgt_class->prepare_func = pinch_precalc; } static void gst_pinch_init (GstPinch * filter, GstPinchClass * gclass) { - filter->x_center = DEFAULT_X_CENTER; - filter->y_center = DEFAULT_Y_CENTER; filter->intensity = DEFAULT_INTENSITY; - filter->radius = DEFAULT_RADIUS; } gboolean diff --git a/gst/geometrictransform/gstpinch.h b/gst/geometrictransform/gstpinch.h index e9a0ddeb1..ed632fcf2 100644 --- a/gst/geometrictransform/gstpinch.h +++ b/gst/geometrictransform/gstpinch.h @@ -45,7 +45,7 @@ #define __GST_PINCH_H__ #include <gst/gst.h> -#include "gstgeometrictransform.h" +#include "gstcirclegeometrictransform.h" G_BEGIN_DECLS @@ -68,20 +68,14 @@ typedef struct _GstPinchClass GstPinchClass; struct _GstPinch { - GstGeometricTransform element; + GstCircleGeometricTransform element; - gdouble x_center; - gdouble y_center; - gdouble radius; gdouble intensity; - - gdouble precalc_x_center; - gdouble precalc_y_center; }; struct _GstPinchClass { - GstGeometricTransformClass parent_class; + GstCircleGeometricTransformClass parent_class; }; GType gst_pinch_get_type (void); |