diff options
author | Filippo Argiolas <filippo.argiolas@gmail.com> | 2010-08-09 08:52:51 +0200 |
---|---|---|
committer | Sebastian Dröge <sebastian.droege@collabora.co.uk> | 2010-08-09 19:25:54 +0200 |
commit | a72b2f5849c0f07a6e520b9eccd2b95d6269a790 (patch) | |
tree | 0c219c05661d6985b23f97fb37fa9ff3d9f016b8 | |
parent | 58b76ac56c515851e9fa1f37e1ff010118bb2dbe (diff) |
geometrictransform: add a "zoom" parameter to bulge filter
Rework bulge mapping function to give more predictable results.
Now the bulge is done dividing by a scale factor that smoothsteps from
"zoom" at the center to 1.0 at "radius".
https://bugzilla.gnome.org/show_bug.cgi?id=625908
-rw-r--r-- | gst/geometrictransform/gstbulge.c | 85 | ||||
-rw-r--r-- | gst/geometrictransform/gstbulge.h | 2 |
2 files changed, 81 insertions, 6 deletions
diff --git a/gst/geometrictransform/gstbulge.c b/gst/geometrictransform/gstbulge.c index 453e33b0f..abfc00963 100644 --- a/gst/geometrictransform/gstbulge.c +++ b/gst/geometrictransform/gstbulge.c @@ -54,9 +54,62 @@ GST_DEBUG_CATEGORY_STATIC (gst_bulge_debug); #define GST_CAT_DEFAULT gst_bulge_debug +enum +{ + PROP_0, + PROP_ZOOM +}; + +#define DEFAULT_ZOOM 3.0 + GST_BOILERPLATE (GstBulge, gst_bulge, GstCircleGeometricTransform, GST_TYPE_CIRCLE_GEOMETRIC_TRANSFORM); +static void +gst_bulge_set_property (GObject * object, guint prop_id, const GValue * value, + GParamSpec * pspec) +{ + GstBulge *bulge; + GstGeometricTransform *gt; + gdouble v; + + gt = GST_GEOMETRIC_TRANSFORM_CAST (object); + bulge = GST_BULGE_CAST (object); + + GST_OBJECT_LOCK (gt); + switch (prop_id) { + case PROP_ZOOM: + v = g_value_get_double (value); + if (v != bulge->zoom) { + bulge->zoom = v; + gst_geometric_transform_set_need_remap (gt); + } + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } + GST_OBJECT_UNLOCK (gt); +} + +static void +gst_bulge_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstBulge *bulge; + + bulge = GST_BULGE_CAST (object); + + switch (prop_id) { + case PROP_ZOOM: + g_value_set_double (value, bulge->zoom); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + /* Clean up */ static void gst_bulge_finalize (GObject * obj) @@ -87,6 +140,7 @@ bulge_map (GstGeometricTransform * gt, gint x, gint y, gdouble * in_x, gdouble norm_x, norm_y; gdouble r; + gdouble scale; gdouble width = gt->width; gdouble height = gt->height; @@ -98,12 +152,20 @@ bulge_map (GstGeometricTransform * gt, gint x, gint y, gdouble * in_x, /* calculate radius, normalize to 1 for future convenience */ r = sqrt (0.5 * (norm_x * norm_x + norm_y * norm_y)); - /* maps r to r^2 in the step region */ - /* interpolating from negative values limits the amount of zoom at - * the center so the first edge could be used as intensity - * parameter */ - norm_x *= smoothstep (-0.15, cgt->radius, r); - norm_y *= smoothstep (-0.15, cgt->radius, r); + /* zoom in the center region and smoothly get back to no zoom while + * r increases */ + + /* the scale factor goes from bulge->zoom when r == 0 to 1.0 + * when r == cgt->radius using Hermite interpolation */ + /* scale is inverted because we're doing an inverse transform so + * zoom is achieved dividing */ + + scale = + 1.0 / (bulge->zoom + ((1.0 - bulge->zoom) * smoothstep (0, cgt->radius, + r))); + + norm_x *= scale; + norm_y *= scale; /* unnormalize */ *in_x = (0.5 * norm_x + cgt->x_center) * width; @@ -126,6 +188,16 @@ gst_bulge_class_init (GstBulgeClass * klass) parent_class = g_type_class_peek_parent (klass); + gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_bulge_set_property); + gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_bulge_get_property); + + + g_object_class_install_property (gobject_class, PROP_ZOOM, + g_param_spec_double ("zoom", "zoom", + "Zoom of the bulge effect", + 1.0, 100.0, DEFAULT_ZOOM, + GST_PARAM_CONTROLLABLE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_bulge_finalize); gstgt_class->map_func = bulge_map; @@ -136,6 +208,7 @@ gst_bulge_init (GstBulge * filter, GstBulgeClass * gclass) { GstGeometricTransform *gt = GST_GEOMETRIC_TRANSFORM (filter); + filter->zoom = DEFAULT_ZOOM; gt->off_edge_pixels = GST_GT_OFF_EDGES_PIXELS_CLAMP; } diff --git a/gst/geometrictransform/gstbulge.h b/gst/geometrictransform/gstbulge.h index 9aa3b405a..03b69e6fc 100644 --- a/gst/geometrictransform/gstbulge.h +++ b/gst/geometrictransform/gstbulge.h @@ -67,6 +67,8 @@ typedef struct _GstBulgeClass GstBulgeClass; struct _GstBulge { GstCircleGeometricTransform element; + + gdouble zoom; }; struct _GstBulgeClass |