2 * wave.c -- wave filter
3 * Author: Leny Grisel <leny.grisel@laposte.net>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program 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
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * aint32_t with this program; if not, write to the Free Software Foundation,
17 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 #include "filter_wave.h"
22 #include <framework/mlt_frame.h>
28 // this is a utility function used by DoWave below
29 static uint8_t getPoint(uint8_t *src
, int w
, int h
, int x
, int y
, int z
)
31 if (x
<0) x
+=-((-x
)%w
)+w
; else if (x
>=w
) x
=x
%w
;
32 if (y
<0) y
+=-((-y
)%h
)+h
; else if (y
>=h
) y
=y
%h
;
33 return src
[(x
+y
*w
)*4+z
];
36 // the main meat of the algorithm lies here
37 static void DoWave(uint8_t *src
, int src_w
, int src_h
, uint8_t *dst
, mlt_position position
, int speed
, int factor
, int deformX
, int deformY
)
40 int decalY
, decalX
, z
;
41 float amplitude
, phase
, pulsation
;
42 register int uneven
= src_w
% 2;
43 int w
= (src_w
- uneven
) / 2;
45 pulsation
= 0.5 / factor
; // smaller means bigger period
46 phase
= position
* pulsation
* speed
/ 10; // smaller means longer
47 for (y
=0;y
<src_h
;y
++) {
48 decalX
= deformX ?
sin(pulsation
* y
+ phase
) * amplitude
: 0;
50 decalY
= deformY ?
sin(pulsation
* x
* 2 + phase
) * amplitude
: 0;
52 *dst
++ = getPoint(src
, w
, src_h
, (x
+decalX
), (y
+decalY
), z
);
55 decalY
= sin(pulsation
* x
* 2 + phase
) * amplitude
;
57 *dst
++ = getPoint(src
, w
, src_h
, (x
+decalX
), (y
+decalY
), z
);
62 static int filter_get_image( mlt_frame
this, uint8_t **image
, mlt_image_format
*format
, int *width
, int *height
, int writable
)
65 int error
= mlt_frame_get_image( this, image
, format
, width
, height
, 1 );
66 mlt_position position
= mlt_frame_get_position( this );
68 // Only process if we have no error and a valid colour space
69 if ( error
== 0 && *format
== mlt_image_yuv422
)
71 double factor
= mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "wave" );
72 int speed
= mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "speed" );
73 int deformX
= mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "deformX" );
74 int deformY
= mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "deformY" );
76 int image_size
= *width
* (*height
+ 1) * 2;
77 int8_t *dest
= mlt_pool_alloc (image_size
);
78 DoWave(*image
, *width
, (*height
+ 1), dest
, position
, speed
, factor
, deformX
, deformY
);
79 memcpy(*image
, dest
, image_size
);
80 mlt_pool_release(dest
);
87 /** Filter processing.
90 static mlt_frame
filter_process( mlt_filter
this, mlt_frame frame
)
92 // Get the starting wave level
93 double wave
= mlt_properties_get_double( MLT_FILTER_PROPERTIES( this ), "start" );
94 int speed
= mlt_properties_get_int( MLT_FILTER_PROPERTIES( this ), "speed" );
95 int deformX
= mlt_properties_get_int( MLT_FILTER_PROPERTIES( this ), "deformX" );
96 int deformY
= mlt_properties_get_int( MLT_FILTER_PROPERTIES( this ), "deformY" );
98 // If there is an end adjust gain to the range
99 if ( mlt_properties_get( MLT_FILTER_PROPERTIES( this ), "end" ) != NULL
)
101 // Determine the time position of this frame in the transition duration
102 mlt_position in
= mlt_filter_get_in( this );
103 mlt_position out
= mlt_filter_get_out( this );
104 mlt_position time
= mlt_frame_get_position( frame
);
105 double position
= ( double )( time
- in
) / ( double )( out
- in
+ 1 );
106 double end
= fabs( mlt_properties_get_double( MLT_FILTER_PROPERTIES( this ), "end" ) );
107 wave
+= ( end
- wave
) * position
;
110 // Push the frame filter
111 mlt_properties_set_double( MLT_FRAME_PROPERTIES( frame
), "wave", wave
);
112 mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame
), "speed", speed
);
113 mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame
), "deformX", deformX
);
114 mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame
), "deformY", deformY
);
115 mlt_frame_push_get_image( frame
, filter_get_image
);
120 /** Constructor for the filter.
123 mlt_filter
filter_wave_init( char *arg
)
125 mlt_filter
this = mlt_filter_new( );
128 this->process
= filter_process
;
129 mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "start", arg
== NULL ?
"10" : arg
);
130 mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "speed", arg
== NULL ?
"5" : arg
);
131 mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "deformX", arg
== NULL ?
"1" : arg
);
132 mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "deformY", arg
== NULL ?
"1" : arg
);