]> git.sesse.net Git - mlt/blob - src/modules/core/filter_mirror.c
Cleanup license declarations and remove dv1394d references.
[mlt] / src / modules / core / filter_mirror.c
1 /*
2  * filter_mirror.c -- mirror filter
3  * Copyright (C) 2003-2004 Ushodaya Enterprises Limited
4  * Author: Charles Yates <charles.yates@pandora.be>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include "filter_mirror.h"
22
23 #include <framework/mlt_frame.h>
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28
29 /** Do it :-).
30 */
31
32 static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable )
33 {
34         // Pop the mirror filter from the stack
35         mlt_filter this = mlt_frame_pop_service( frame );
36
37         // Get the mirror type
38         mlt_properties properties = MLT_FILTER_PROPERTIES( this );
39
40         // Get the properties
41         char *mirror = mlt_properties_get( properties, "mirror" );
42
43         // Determine if reverse is required
44         int reverse = mlt_properties_get_int( properties, "reverse" );
45
46         // Get the image
47         int error = mlt_frame_get_image( frame, image, format, width, height, 1 );
48
49         // Get the alpha
50         uint8_t *alpha = mlt_frame_get_alpha_mask( frame );
51
52         // If we have an image of the right colour space
53         if ( error == 0 && *format == mlt_image_yuv422 )
54         {
55                 // We'll KISS here
56                 int hh = *height / 2;
57
58                 if ( !strcmp( mirror, "horizontal" ) )
59                 {
60                         uint8_t *p = NULL;
61                         uint8_t *q = NULL;
62                         uint8_t *a = NULL;
63                         uint8_t *b = NULL;
64                         int i;
65                         int uneven_w = ( *width % 2 ) * 2;
66                         for ( i = 0; i < *height; i ++ )
67                         {
68                                 p = ( uint8_t * )*image + i * *width * 2;
69                                 q = p + *width * 2;
70                                 a = alpha + i * *width;
71                                 b = a + *width - 1;
72                                 if ( !reverse )
73                                 {
74                                         while ( p < q )
75                                         {
76                                                 *p ++ = *( q - 2 );
77                                                 *p ++ = *( q - 3 - uneven_w );
78                                                 *p ++ = *( q - 4 );
79                                                 *p ++ = *( q - 1 - uneven_w );
80                                                 q -= 4;
81                                                 *a ++ = *b --;
82                                                 *a ++ = *b --;
83                                         }
84                                 }
85                                 else
86                                 {
87                                         while ( p < q )
88                                         {
89                                                 *( q - 2 ) = *p ++;
90                                                 *( q - 3 - uneven_w ) = *p ++;
91                                                 *( q - 4 ) = *p ++;
92                                                 *( q - 1 - uneven_w ) = *p ++;
93                                                 q -= 4;
94                                                 *b -- = *a ++;
95                                                 *b -- = *a ++;
96                                         }
97                                 }
98                         }
99                 }
100                 else if ( !strcmp( mirror, "vertical" ) )
101                 {
102                         uint16_t *end = ( uint16_t *)*image + *width * *height;
103                         uint16_t *p = NULL;
104                         uint16_t *q = NULL;
105                         uint8_t *a = NULL;
106                         uint8_t *b = NULL;
107                         int i;
108                         int j;
109                         for ( i = 0; i < hh; i ++ )
110                         {
111                                 p = ( uint16_t * )*image + i * *width;
112                                 q = end - ( i + 1 ) * *width;
113                                 j = *width;
114                                 a = alpha + i * *width;
115                                 b = alpha + ( *height - i - 1 ) * *width;
116                                 if ( !reverse )
117                                 {
118                                         while ( j -- )
119                                         {
120                                                 *p ++ = *q ++;
121                                                 *a ++ = *b ++;
122                                         }
123                                 }
124                                 else
125                                 {
126                                         while ( j -- )
127                                         {
128                                                 *q ++ = *p ++;
129                                                 *b ++ = *a ++;
130                                         }
131                                 }
132                         }
133                 }
134                 else if ( !strcmp( mirror, "diagonal" ) )
135                 {
136                         uint8_t *end = ( uint8_t *)*image + *width * *height * 2;
137                         uint8_t *p = NULL;
138                         uint8_t *q = NULL;
139                         uint8_t *a = NULL;
140                         uint8_t *b = NULL;
141                         int i;
142                         int j;
143                         int uneven_w = ( *width % 2 ) * 2;
144                         for ( i = 0; i < *height; i ++ )
145                         {
146                                 p = ( uint8_t * )*image + i * *width * 2;
147                                 q = end - i * *width * 2;
148                                 j = ( ( *width * ( *height - i ) ) / *height ) / 2;
149                                 a = alpha + i * *width;
150                                 b = alpha + ( *height - i - 1 ) * *width;
151                                 if ( !reverse )
152                                 {
153                                         while ( j -- )
154                                         {
155                                                 *p ++ = *( q - 2 );
156                                                 *p ++ = *( q - 3 - uneven_w );
157                                                 *p ++ = *( q - 4 );
158                                                 *p ++ = *( q - 1 - uneven_w );
159                                                 q -= 4;
160                                                 *a ++ = *b --;
161                                                 *a ++ = *b --;
162                                         }
163                                 }
164                                 else
165                                 {
166                                         while ( j -- )
167                                         {
168                                                 *( q - 2 ) = *p ++;
169                                                 *( q - 3 - uneven_w ) = *p ++;
170                                                 *( q - 4 ) = *p ++;
171                                                 *( q - 1 - uneven_w ) = *p ++;
172                                                 q -= 4;
173                                                 *b -- = *a ++;
174                                                 *b -- = *a ++;
175                                         }
176                                 }
177                         }
178                 }
179                 else if ( !strcmp( mirror, "xdiagonal" ) )
180                 {
181                         uint8_t *end = ( uint8_t *)*image + *width * *height * 2;
182                         uint8_t *p = NULL;
183                         uint8_t *q = NULL;
184                         int i;
185                         int j;
186                         uint8_t *a = NULL;
187                         uint8_t *b = NULL;
188                         int uneven_w = ( *width % 2 ) * 2;
189                         for ( i = 0; i < *height; i ++ )
190                         {
191                                 p = ( uint8_t * )*image + ( i + 1 ) * *width * 2;
192                                 q = end - ( i + 1 ) * *width * 2;
193                                 j = ( ( *width * ( *height - i ) ) / *height ) / 2;
194                                 a = alpha + ( i + 1 ) * *width - 1;
195                                 b = alpha + ( *height - i - 1 ) * *width;
196                                 if ( !reverse )
197                                 {
198                                         while ( j -- )
199                                         {
200                                                 *q ++ = *( p - 2 );
201                                                 *q ++ = *( p - 3 - uneven_w );
202                                                 *q ++ = *( p - 4 );
203                                                 *q ++ = *( p - 1 - uneven_w );
204                                                 p -= 4;
205                                                 *b ++ = *a --;
206                                                 *b ++ = *a --;
207                                         }
208                                 }
209                                 else
210                                 {
211                                         while ( j -- )
212                                         {
213                                                 *( p - 2 ) = *q ++;
214                                                 *( p - 3 - uneven_w ) = *q ++;
215                                                 *( p - 4 ) = *q ++;
216                                                 *( p - 1 - uneven_w ) = *q ++;
217                                                 p -= 4;
218                                                 *a -- = *b ++;
219                                                 *a -- = *b ++;
220                                         }
221                                 }
222                         }
223                 }
224                 else if ( !strcmp( mirror, "flip" ) )
225                 {
226                         uint8_t t[ 4 ];
227                         uint8_t *p = NULL;
228                         uint8_t *q = NULL;
229                         int i;
230                         uint8_t *a = NULL;
231                         uint8_t *b = NULL;
232                         uint8_t c;
233                         int uneven_w = ( *width % 2 ) * 2;
234                         for ( i = 0; i < *height; i ++ )
235                         {
236                                 p = ( uint8_t * )*image + i * *width * 2;
237                                 q = p + *width * 2;
238                                 a = alpha + i * *width;
239                                 b = a + *width - 1;
240                                 while ( p < q )
241                                 {
242                                         t[ 0 ] = p[ 0 ];
243                                         t[ 1 ] = p[ 1 + uneven_w ];
244                                         t[ 2 ] = p[ 2 ];
245                                         t[ 3 ] = p[ 3 + uneven_w ];
246                                         *p ++ = *( q - 2 );
247                                         *p ++ = *( q - 3 - uneven_w );
248                                         *p ++ = *( q - 4 );
249                                         *p ++ = *( q - 1 - uneven_w );
250                                         *( -- q ) = t[ 3 ];
251                                         *( -- q ) = t[ 0 ];
252                                         *( -- q ) = t[ 1 ];
253                                         *( -- q ) = t[ 2 ];
254                                         c = *a;
255                                         *a ++ = *b;
256                                         *b -- = c;
257                                         c = *a;
258                                         *a ++ = *b;
259                                         *b -- = c;
260                                 }
261                         }
262                 }
263                 else if ( !strcmp( mirror, "flop" ) )
264                 {
265                         uint16_t *end = ( uint16_t *)*image + *width * *height;
266                         uint16_t *p = NULL;
267                         uint16_t *q = NULL;
268                         uint16_t t;
269                         uint8_t *a = NULL;
270                         uint8_t *b = NULL;
271                         uint8_t c;
272                         int i;
273                         int j;
274                         for ( i = 0; i < hh; i ++ )
275                         {
276                                 p = ( uint16_t * )*image + i * *width;
277                                 q = end - ( i + 1 ) * *width;
278                                 a = alpha + i * *width;
279                                 b = alpha + ( *height - i - 1 ) * *width;
280                                 j = *width;
281                                 while ( j -- )
282                                 {
283                                         t = *p;
284                                         *p ++ = *q;
285                                         *q ++ = t;
286                                         c = *a;
287                                         *a ++ = *b;
288                                         *b ++ = c;
289                                 }
290                         }
291                 }
292         }
293
294         // Return the error
295         return error;
296 }
297
298 /** Filter processing.
299 */
300
301 static mlt_frame filter_process( mlt_filter this, mlt_frame frame )
302 {
303         // Push the service on to the stack
304         mlt_frame_push_service( frame, this );
305
306         // Push the filter method on to the stack
307         mlt_frame_push_service( frame, filter_get_image );
308
309         return frame;
310 }
311
312 /** Constructor for the filter.
313 */
314
315 mlt_filter filter_mirror_init( void *arg )
316 {
317         // Construct a new filter
318         mlt_filter this = mlt_filter_new( );
319
320         // If we have a filter, initialise it
321         if ( this != NULL )
322         {
323                 // Get the properties
324                 mlt_properties properties = MLT_FILTER_PROPERTIES( this );
325
326                 // Set the default mirror type
327                 mlt_properties_set_or_default( properties, "mirror", arg, "horizontal" );
328
329                 // Assign the process method
330                 this->process = filter_process;
331         }
332
333         // Return the filter
334         return this;
335 }
336