Way, way, way too many files: Remove crack comment from the 2000 era.
[platform/upstream/gst-plugins-good.git] / gst / videofilter / gstvideoflip.c
1 /* GStreamer
2  * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3  * Copyright (C) <2003> David Schleef <ds@schleef.org>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 /*
22  * This file was (probably) generated from gstvideoflip.c,
23  * gstvideoflip.c,v 1.7 2003/11/08 02:48:59 dschleef Exp 
24  */
25
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29
30 /*#define DEBUG_ENABLED */
31 #include "gstvideoflip.h"
32 #include <string.h>
33
34 /* GstVideoflip signals and args */
35 enum
36 {
37   /* FILL ME */
38   LAST_SIGNAL
39 };
40
41 enum
42 {
43   ARG_0,
44   ARG_METHOD
45       /* FILL ME */
46 };
47
48 static void gst_videoflip_base_init (gpointer g_class);
49 static void gst_videoflip_class_init (gpointer g_class, gpointer class_data);
50 static void gst_videoflip_init (GTypeInstance * instance, gpointer g_class);
51
52 static void gst_videoflip_set_property (GObject * object, guint prop_id,
53     const GValue * value, GParamSpec * pspec);
54 static void gst_videoflip_get_property (GObject * object, guint prop_id,
55     GValue * value, GParamSpec * pspec);
56
57 static void gst_videoflip_planar411 (GstVideofilter * videofilter, void *dest,
58     void *src);
59 static void gst_videoflip_setup (GstVideofilter * videofilter);
60
61 #define GST_TYPE_VIDEOFLIP_METHOD (gst_videoflip_method_get_type())
62
63 static GType
64 gst_videoflip_method_get_type (void)
65 {
66   static GType videoflip_method_type = 0;
67   static GEnumValue videoflip_methods[] = {
68     {GST_VIDEOFLIP_METHOD_IDENTITY, "0", "Identity (no rotation)"},
69     {GST_VIDEOFLIP_METHOD_90R, "1", "Rotate clockwise 90 degrees"},
70     {GST_VIDEOFLIP_METHOD_180, "2", "Rotate 180 degrees"},
71     {GST_VIDEOFLIP_METHOD_90L, "3", "Rotate counter-clockwise 90 degrees"},
72     {GST_VIDEOFLIP_METHOD_HORIZ, "4", "Flip horizontally"},
73     {GST_VIDEOFLIP_METHOD_VERT, "5", "Flip vertically"},
74     {GST_VIDEOFLIP_METHOD_TRANS, "6",
75         "Flip across upper left/lower right diagonal"},
76     {GST_VIDEOFLIP_METHOD_OTHER, "7",
77         "Flip across upper right/lower left diagonal"},
78     {0, NULL, NULL},
79   };
80
81   if (!videoflip_method_type) {
82     videoflip_method_type = g_enum_register_static ("GstVideoflipMethod",
83         videoflip_methods);
84   }
85   return videoflip_method_type;
86 }
87
88 GType
89 gst_videoflip_get_type (void)
90 {
91   static GType videoflip_type = 0;
92
93   if (!videoflip_type) {
94     static const GTypeInfo videoflip_info = {
95       sizeof (GstVideoflipClass),
96       gst_videoflip_base_init,
97       NULL,
98       gst_videoflip_class_init,
99       NULL,
100       NULL,
101       sizeof (GstVideoflip),
102       0,
103       gst_videoflip_init,
104     };
105
106     videoflip_type = g_type_register_static (GST_TYPE_VIDEOFILTER,
107         "GstVideoflip", &videoflip_info, 0);
108   }
109   return videoflip_type;
110 }
111
112 static GstVideofilterFormat gst_videoflip_formats[] = {
113   /* planar */
114   {"YV12", 12, gst_videoflip_planar411,},
115   {"I420", 12, gst_videoflip_planar411,},
116   {"IYUV", 12, gst_videoflip_planar411,},
117 };
118
119 static void
120 gst_videoflip_base_init (gpointer g_class)
121 {
122   static GstElementDetails videoflip_details =
123       GST_ELEMENT_DETAILS ("Video Flipper",
124       "Filter/Effect/Video",
125       "Flips and rotates video",
126       "David Schleef <ds@schleef.org>");
127   GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
128   GstVideofilterClass *videofilter_class = GST_VIDEOFILTER_CLASS (g_class);
129   int i;
130
131   gst_element_class_set_details (element_class, &videoflip_details);
132
133   for (i = 0; i < G_N_ELEMENTS (gst_videoflip_formats); i++) {
134     gst_videofilter_class_add_format (videofilter_class,
135         gst_videoflip_formats + i);
136   }
137
138   gst_videofilter_class_add_pad_templates (GST_VIDEOFILTER_CLASS (g_class));
139 }
140
141 static void
142 gst_videoflip_class_init (gpointer g_class, gpointer class_data)
143 {
144   GObjectClass *gobject_class;
145   GstVideofilterClass *videofilter_class;
146
147   gobject_class = G_OBJECT_CLASS (g_class);
148   videofilter_class = GST_VIDEOFILTER_CLASS (g_class);
149
150   gobject_class->set_property = gst_videoflip_set_property;
151   gobject_class->get_property = gst_videoflip_get_property;
152
153   g_object_class_install_property (gobject_class, ARG_METHOD,
154       g_param_spec_enum ("method", "method", "method",
155           GST_TYPE_VIDEOFLIP_METHOD, GST_VIDEOFLIP_METHOD_90R,
156           G_PARAM_READWRITE));
157
158   videofilter_class->setup = gst_videoflip_setup;
159 }
160
161 static void
162 gst_videoflip_init (GTypeInstance * instance, gpointer g_class)
163 {
164   GstVideoflip *videoflip = GST_VIDEOFLIP (instance);
165   GstVideofilter *videofilter;
166
167   GST_DEBUG ("gst_videoflip_init");
168
169   videofilter = GST_VIDEOFILTER (videoflip);
170
171   /* do stuff */
172 }
173
174 static void
175 gst_videoflip_set_property (GObject * object, guint prop_id,
176     const GValue * value, GParamSpec * pspec)
177 {
178   GstVideoflip *src;
179
180   g_return_if_fail (GST_IS_VIDEOFLIP (object));
181   src = GST_VIDEOFLIP (object);
182
183   GST_DEBUG ("gst_videoflip_set_property");
184   switch (prop_id) {
185     case ARG_METHOD:
186       src->method = g_value_get_enum (value);
187       /* FIXME is this ok? (threading issues) */
188       gst_videoflip_setup (GST_VIDEOFILTER (src));
189       break;
190     default:
191       break;
192   }
193 }
194
195 static void
196 gst_videoflip_get_property (GObject * object, guint prop_id, GValue * value,
197     GParamSpec * pspec)
198 {
199   GstVideoflip *src;
200
201   g_return_if_fail (GST_IS_VIDEOFLIP (object));
202   src = GST_VIDEOFLIP (object);
203
204   switch (prop_id) {
205     case ARG_METHOD:
206       g_value_set_enum (value, src->method);
207       break;
208     default:
209       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
210       break;
211   }
212 }
213
214 static gboolean
215 plugin_init (GstPlugin * plugin)
216 {
217   if (!gst_library_load ("gstvideofilter"))
218     return FALSE;
219
220   return gst_element_register (plugin, "videoflip", GST_RANK_NONE,
221       GST_TYPE_VIDEOFLIP);
222 }
223
224 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
225     GST_VERSION_MINOR,
226     "videoflip",
227     "Flips and rotates video",
228     plugin_init, VERSION, GST_LICENSE, GST_PACKAGE, GST_ORIGIN)
229
230      static void gst_videoflip_flip (GstVideoflip * videoflip,
231     unsigned char *dest, unsigned char *src, int sw, int sh, int dw, int dh);
232
233
234      static void gst_videoflip_setup (GstVideofilter * videofilter)
235 {
236   int from_width, from_height;
237   GstVideoflip *videoflip;
238
239   GST_DEBUG ("gst_videoflip_setup");
240
241   videoflip = GST_VIDEOFLIP (videofilter);
242
243   from_width = gst_videofilter_get_input_width (videofilter);
244   from_height = gst_videofilter_get_input_height (videofilter);
245
246   if (from_width == 0 || from_height == 0) {
247     return;
248   }
249
250   switch (videoflip->method) {
251     case GST_VIDEOFLIP_METHOD_90R:
252     case GST_VIDEOFLIP_METHOD_90L:
253     case GST_VIDEOFLIP_METHOD_TRANS:
254     case GST_VIDEOFLIP_METHOD_OTHER:
255       gst_videofilter_set_output_size (videofilter, from_height, from_width);
256       break;
257     case GST_VIDEOFLIP_METHOD_IDENTITY:
258     case GST_VIDEOFLIP_METHOD_180:
259     case GST_VIDEOFLIP_METHOD_HORIZ:
260     case GST_VIDEOFLIP_METHOD_VERT:
261       gst_videofilter_set_output_size (videofilter, from_width, from_height);
262       break;
263     default:
264       g_assert_not_reached ();
265       break;
266   }
267
268   GST_DEBUG ("format=%p \"%s\" from %dx%d to %dx%d",
269       videofilter->format, videofilter->format->fourcc,
270       from_width, from_height, videofilter->to_width, videofilter->to_height);
271
272   if (videoflip->method == GST_VIDEOFLIP_METHOD_IDENTITY) {
273     GST_DEBUG ("videoflip: using passthru");
274     videofilter->passthru = TRUE;
275   } else {
276     videofilter->passthru = FALSE;
277   }
278
279   videofilter->from_buf_size =
280       (videofilter->from_width * videofilter->from_height *
281       videofilter->format->depth) / 8;
282   videofilter->to_buf_size =
283       (videofilter->to_width * videofilter->to_height *
284       videofilter->format->depth) / 8;
285
286   videofilter->inited = TRUE;
287 }
288
289 static void
290 gst_videoflip_planar411 (GstVideofilter * videofilter, void *dest, void *src)
291 {
292   GstVideoflip *videoflip;
293   int sw;
294   int sh;
295   int dw;
296   int dh;
297
298   g_return_if_fail (GST_IS_VIDEOFLIP (videofilter));
299   videoflip = GST_VIDEOFLIP (videofilter);
300
301   sw = videofilter->from_width;
302   sh = videofilter->from_height;
303   dw = videofilter->to_width;
304   dh = videofilter->to_height;
305
306   GST_DEBUG ("videoflip: scaling planar 4:1:1 %dx%d to %dx%d", sw, sh, dw, dh);
307
308   gst_videoflip_flip (videoflip, dest, src, sw, sh, dw, dh);
309
310   src += sw * sh;
311   dest += dw * dh;
312
313   dh = dh >> 1;
314   dw = dw >> 1;
315   sh = sh >> 1;
316   sw = sw >> 1;
317
318   gst_videoflip_flip (videoflip, dest, src, sw, sh, dw, dh);
319
320   src += sw * sh;
321   dest += dw * dh;
322
323   gst_videoflip_flip (videoflip, dest, src, sw, sh, dw, dh);
324 }
325
326 static void
327 gst_videoflip_flip (GstVideoflip * videoflip, unsigned char *dest,
328     unsigned char *src, int sw, int sh, int dw, int dh)
329 {
330   int x, y;
331
332   switch (videoflip->method) {
333     case GST_VIDEOFLIP_METHOD_90R:
334       for (y = 0; y < dh; y++) {
335         for (x = 0; x < dw; x++) {
336           dest[y * dw + x] = src[(sh - 1 - x) * sw + y];
337         }
338       }
339       break;
340     case GST_VIDEOFLIP_METHOD_90L:
341       for (y = 0; y < dh; y++) {
342         for (x = 0; x < dw; x++) {
343           dest[y * dw + x] = src[x * sw + (sw - 1 - y)];
344         }
345       }
346       break;
347     case GST_VIDEOFLIP_METHOD_180:
348       for (y = 0; y < dh; y++) {
349         for (x = 0; x < dw; x++) {
350           dest[y * dw + x] = src[(sh - 1 - y) * sw + (sw - 1 - x)];
351         }
352       }
353       break;
354     case GST_VIDEOFLIP_METHOD_HORIZ:
355       for (y = 0; y < dh; y++) {
356         for (x = 0; x < dw; x++) {
357           dest[y * dw + x] = src[y * sw + (sw - 1 - x)];
358         }
359       }
360       break;
361     case GST_VIDEOFLIP_METHOD_VERT:
362       for (y = 0; y < dh; y++) {
363         for (x = 0; x < dw; x++) {
364           dest[y * dw + x] = src[(sh - 1 - y) * sw + x];
365         }
366       }
367       break;
368     case GST_VIDEOFLIP_METHOD_TRANS:
369       for (y = 0; y < dh; y++) {
370         for (x = 0; x < dw; x++) {
371           dest[y * dw + x] = src[x * sw + y];
372         }
373       }
374       break;
375     case GST_VIDEOFLIP_METHOD_OTHER:
376       for (y = 0; y < dh; y++) {
377         for (x = 0; x < dw; x++) {
378           dest[y * dw + x] = src[(sh - 1 - x) * sw + (sw - 1 - y)];
379         }
380       }
381       break;
382     default:
383       /* FIXME */
384       break;
385   }
386 }