2 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
5 * Copyright (C) 2001 FUKUCHI Kentarou
7 * Inspired by Adrian Likin's script for the GIMP.
8 * EffecTV is free software. This library is free software;
9 * you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
19 * You should have received a copy of the GNU Library General Public
20 * License along with this library; if not, write to the
21 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 * Boston, MA 02111-1307, USA.
31 #include <gstvideofilter.h>
33 #define GST_TYPE_SHAGADELICTV \
34 (gst_shagadelictv_get_type())
35 #define GST_SHAGADELICTV(obj) \
36 (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SHAGADELICTV,GstShagadelicTV))
37 #define GST_SHAGADELICTV_CLASS(klass) \
38 (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SHAGADELICTV,GstShagadelicTVClass))
39 #define GST_IS_SHAGADELICTV(obj) \
40 (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SHAGADELICTV))
41 #define GST_IS_SHAGADELICTV_CLASS(obj) \
42 (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SHAGADELICTV))
44 typedef struct _GstShagadelicTV GstShagadelicTV;
45 typedef struct _GstShagadelicTVClass GstShagadelicTVClass;
47 struct _GstShagadelicTV
49 GstVideofilter videofilter;
62 struct _GstShagadelicTVClass
64 GstVideofilterClass parent_class;
67 /* Filter signals and args */
79 static void gst_shagadelictv_base_init (gpointer g_class);
80 static void gst_shagadelictv_class_init (gpointer g_class, gpointer class_data);
81 static void gst_shagadelictv_init (GTypeInstance * instance, gpointer g_class);
83 static void gst_shagadelic_initialize (GstShagadelicTV * filter);
85 static void gst_shagadelictv_set_property (GObject * object, guint prop_id,
86 const GValue * value, GParamSpec * pspec);
87 static void gst_shagadelictv_get_property (GObject * object, guint prop_id,
88 GValue * value, GParamSpec * pspec);
89 static void gst_shagadelictv_setup (GstVideofilter * videofilter);
90 static void gst_shagadelictv_rgb32 (GstVideofilter * videofilter, void *d,
93 /*static guint gst_shagadelictv_signals[LAST_SIGNAL] = { 0 }; */
96 gst_shagadelictv_get_type (void)
98 static GType shagadelictv_type = 0;
100 if (!shagadelictv_type) {
101 static const GTypeInfo shagadelictv_info = {
102 sizeof (GstShagadelicTVClass),
103 gst_shagadelictv_base_init,
105 (GClassInitFunc) gst_shagadelictv_class_init,
108 sizeof (GstShagadelicTV),
110 (GInstanceInitFunc) gst_shagadelictv_init,
114 g_type_register_static (GST_TYPE_VIDEOFILTER, "GstShagadelicTV",
115 &shagadelictv_info, 0);
117 return shagadelictv_type;
120 static GstVideofilterFormat gst_shagadelictv_formats[] = {
121 {"RGB ", 32, gst_shagadelictv_rgb32, 24, G_BIG_ENDIAN, 0x0000ff00, 0x00ff0000,
126 gst_shagadelictv_base_init (gpointer g_class)
128 /* elementfactory information */
129 static GstElementDetails gst_shagadelictv_details =
130 GST_ELEMENT_DETAILS ("ShagadelicTV",
131 "Filter/Effect/Video",
132 "Oh behave, ShagedelicTV makes images shagadelic!",
133 "Wim Taymans <wim.taymans@chello.be>");
135 GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
136 GstVideofilterClass *videofilter_class = GST_VIDEOFILTER_CLASS (g_class);
139 gst_element_class_set_details (element_class, &gst_shagadelictv_details);
141 for (i = 0; i < G_N_ELEMENTS (gst_shagadelictv_formats); i++) {
142 gst_videofilter_class_add_format (videofilter_class,
143 gst_shagadelictv_formats + i);
146 gst_videofilter_class_add_pad_templates (GST_VIDEOFILTER_CLASS (g_class));
150 gst_shagadelictv_class_init (gpointer g_class, gpointer class_data)
152 GObjectClass *gobject_class;
153 GstVideofilterClass *videofilter_class;
155 gobject_class = G_OBJECT_CLASS (g_class);
156 videofilter_class = GST_VIDEOFILTER_CLASS (g_class);
158 gobject_class->set_property = gst_shagadelictv_set_property;
159 gobject_class->get_property = gst_shagadelictv_get_property;
161 videofilter_class->setup = gst_shagadelictv_setup;
165 gst_shagadelictv_init (GTypeInstance * instance, gpointer g_class)
167 GstShagadelicTV *filter = GST_SHAGADELICTV (instance);
169 filter->ripple = NULL;
170 filter->spiral = NULL;
174 gst_shagadelictv_setup (GstVideofilter * videofilter)
176 GstShagadelicTV *filter;
177 int width = gst_videofilter_get_input_width (videofilter);
178 int height = gst_videofilter_get_input_height (videofilter);
181 g_return_if_fail (GST_IS_SHAGADELICTV (videofilter));
182 filter = GST_SHAGADELICTV (videofilter);
184 filter->width = width;
185 filter->height = height;
187 area = filter->width * filter->height;
189 g_free (filter->ripple);
190 g_free (filter->spiral);
192 filter->ripple = (gchar *) g_malloc (area * 4);
193 filter->spiral = (gchar *) g_malloc (area);
195 gst_shagadelic_initialize (filter);
201 static unsigned int fastrand_val;
203 return (fastrand_val = fastrand_val * 1103515245 + 12345);
207 gst_shagadelic_initialize (GstShagadelicTV * filter)
218 for (y = 0; y < filter->height * 2; y++) {
219 yy = y - filter->height;
222 for (x = 0; x < filter->width * 2; x++) {
223 xx = x - filter->width;
225 filter->ripple[i++] = ((unsigned int) (sqrtf (xx * xx + yy) * 8)) & 255;
227 filter->ripple[i++] = ((unsigned int) (sqrt (xx * xx + yy) * 8)) & 255;
233 for (y = 0; y < filter->height; y++) {
234 yy = y - filter->height / 2;
236 for (x = 0; x < filter->width; x++) {
237 xx = x - filter->width / 2;
239 filter->spiral[i++] = ((unsigned int)
241 yy) / ((float) M_PI) * 256 * 9) + (sqrtf (xx * xx +
242 yy * yy) * 5))) & 255;
244 filter->spiral[i++] = ((unsigned int)
245 ((atan2 (xx, yy) / M_PI * 256 * 9) + (sqrt (xx * xx +
246 yy * yy) * 5))) & 255;
248 /* Here is another Swinger!
249 * ((atan2(xx, yy)/M_PI*256) + (sqrt(xx*xx+yy*yy)*10))&255;
253 filter->rx = fastrand () % filter->width;
254 filter->ry = fastrand () % filter->height;
255 filter->bx = fastrand () % filter->width;
256 filter->by = fastrand () % filter->height;
265 gst_shagadelictv_rgb32 (GstVideofilter * videofilter, void *d, void *s)
267 GstShagadelicTV *filter;
274 filter = GST_SHAGADELICTV (videofilter);
277 dest = (guint32 *) d;
279 width = filter->width;
280 height = filter->height;
282 for (y = 0; y < height; y++) {
283 for (x = 0; x < width; x++) {
284 v = *src++ | 0x1010100;
285 v = (v - 0x707060) & 0x1010100;
289 * *dest++ = v & ((r<<16)|(g<<8)|b);
291 r = (gchar) (filter->ripple[(filter->ry + y) * width * 2 + filter->rx +
292 x] + filter->phase * 2) >> 7;
293 g = (gchar) (filter->spiral[y * width + x] + filter->phase * 3) >> 7;
294 b = (gchar) (filter->ripple[(filter->by + y) * width * 2 + filter->bx +
295 x] - filter->phase) >> 7;
296 *dest++ = v & ((r << 16) | (g << 8) | b);
301 if ((filter->rx + filter->rvx) < 0 || (filter->rx + filter->rvx) >= width)
302 filter->rvx = -filter->rvx;
303 if ((filter->ry + filter->rvy) < 0 || (filter->ry + filter->rvy) >= height)
304 filter->rvy = -filter->rvy;
305 if ((filter->bx + filter->bvx) < 0 || (filter->bx + filter->bvx) >= width)
306 filter->bvx = -filter->bvx;
307 if ((filter->by + filter->bvy) < 0 || (filter->by + filter->bvy) >= height)
308 filter->bvy = -filter->bvy;
309 filter->rx += filter->rvx;
310 filter->ry += filter->rvy;
311 filter->bx += filter->bvx;
312 filter->by += filter->bvy;
316 gst_shagadelictv_set_property (GObject * object, guint prop_id,
317 const GValue * value, GParamSpec * pspec)
319 GstShagadelicTV *filter;
321 /* it's not null if we got it, but it might not be ours */
322 g_return_if_fail (GST_IS_SHAGADELICTV (object));
324 filter = GST_SHAGADELICTV (object);
333 gst_shagadelictv_get_property (GObject * object, guint prop_id, GValue * value,
336 GstShagadelicTV *filter;
338 /* it's not null if we got it, but it might not be ours */
339 g_return_if_fail (GST_IS_SHAGADELICTV (object));
341 filter = GST_SHAGADELICTV (object);
345 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);