]> git.sesse.net Git - mlt/blob - src/modules/kdenlive/filter_wave.c
Cleanup copyrights and attributions, and move Jean-Baptiste's services to a new kdenl...
[mlt] / src / modules / kdenlive / filter_wave.c
1 /*
2  * wave.c -- wave filter
3  * Author: Leny Grisel <leny.grisel@laposte.net>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 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  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19
20 #include "filter_wave.h"
21
22 #include <framework/mlt_frame.h>
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <math.h>
27
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)
30 {
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];
34 }
35
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)
38 {
39         register int x, y;
40         int decalY, decalX, z;
41         float amplitude, phase, pulsation;
42         register int uneven = src_w % 2;
43         int w = (src_w - uneven ) / 2;
44         amplitude = factor;
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;
49                 for (x=0;x<w;x++) {
50                         decalY = deformY ? sin(pulsation * x * 2 + phase) * amplitude : 0;
51                         for (z=0; z<4; z++)
52                                 *dst++ = getPoint(src, w, src_h, (x+decalX), (y+decalY), z);
53                 }
54                 if (uneven) {
55                         decalY = sin(pulsation * x * 2 + phase) * amplitude;
56                         for (z=0; z<2; z++)
57                                 *dst++ = getPoint(src, w, src_h, (x+decalX), (y+decalY), z);
58                 }
59         }
60 }
61
62 static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable )
63 {
64         // Get the image
65         int error = mlt_frame_get_image( this, image, format, width, height, 1 );
66         mlt_position position = mlt_frame_get_position( this );
67
68         // Only process if we have no error and a valid colour space
69         if ( error == 0 && *format == mlt_image_yuv422 )
70         {
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" );
75                 if (factor != 0) {
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);
81                 }
82         }
83
84         return error;
85 }
86
87 /** Filter processing.
88 */
89
90 static mlt_frame filter_process( mlt_filter this, mlt_frame frame )
91 {
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" );
97
98         // If there is an end adjust gain to the range
99         if ( mlt_properties_get( MLT_FILTER_PROPERTIES( this ), "end" ) != NULL )
100         {
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;
108         }
109
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 );
116
117         return frame;
118 }
119
120 /** Constructor for the filter.
121 */
122
123 mlt_filter filter_wave_init( char *arg )
124 {
125         mlt_filter this = mlt_filter_new( );
126         if ( this != NULL )
127         {
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);
133                 }
134         return this;
135 }
136
137
138