]> git.sesse.net Git - mlt/blob - src/modules/kdenlive/filter_wave.c
avformat/factory.c, jackrack/jack_rack.c, jackrack/plugin_settings.c, vmfx/filter_chr...
[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 #include <string.h>
28
29 // this is a utility function used by DoWave below
30 static uint8_t getPoint(uint8_t *src, int w, int h, int x, int y, int z)
31 {
32         if (x<0) x+=-((-x)%w)+w; else if (x>=w) x=x%w;
33         if (y<0) y+=-((-y)%h)+h; else if (y>=h) y=y%h;
34         return src[(x+y*w)*4+z];
35 }
36
37 // the main meat of the algorithm lies here
38 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)
39 {
40         register int x, y;
41         int decalY, decalX, z;
42         float amplitude, phase, pulsation;
43         register int uneven = src_w % 2;
44         int w = (src_w - uneven ) / 2;
45         amplitude = factor;
46         pulsation = 0.5 / factor;   // smaller means bigger period
47         phase = position * pulsation * speed / 10; // smaller means longer
48         for (y=0;y<src_h;y++) {
49                 decalX = deformX ? sin(pulsation * y + phase) * amplitude : 0;
50                 for (x=0;x<w;x++) {
51                         decalY = deformY ? sin(pulsation * x * 2 + phase) * amplitude : 0;
52                         for (z=0; z<4; z++)
53                                 *dst++ = getPoint(src, w, src_h, (x+decalX), (y+decalY), z);
54                 }
55                 if (uneven) {
56                         decalY = sin(pulsation * x * 2 + phase) * amplitude;
57                         for (z=0; z<2; z++)
58                                 *dst++ = getPoint(src, w, src_h, (x+decalX), (y+decalY), z);
59                 }
60         }
61 }
62
63 static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable )
64 {
65         // Get the image
66         int error = mlt_frame_get_image( this, image, format, width, height, 1 );
67         mlt_position position = mlt_frame_get_position( this );
68
69         // Only process if we have no error and a valid colour space
70         if ( error == 0 && *format == mlt_image_yuv422 )
71         {
72                 double factor = mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "wave" );
73                 int speed = mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "speed" );
74                 int deformX = mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "deformX" );
75                 int deformY = mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "deformY" );
76                 if (factor != 0) {
77                         int image_size = *width * (*height + 1) * 2;
78                         uint8_t *dest = mlt_pool_alloc (image_size);
79                         DoWave(*image, *width, (*height + 1), dest, position, speed, factor, deformX, deformY);
80                         memcpy(*image, dest, image_size);
81                         mlt_pool_release(dest);
82                 }
83         }
84
85         return error;
86 }
87
88 /** Filter processing.
89 */
90
91 static mlt_frame filter_process( mlt_filter this, mlt_frame frame )
92 {
93         // Get the starting wave level
94         double wave = mlt_properties_get_double( MLT_FILTER_PROPERTIES( this ), "start" );
95         int speed = mlt_properties_get_int( MLT_FILTER_PROPERTIES( this ), "speed" );
96         int deformX = mlt_properties_get_int( MLT_FILTER_PROPERTIES( this ), "deformX" );
97         int deformY = mlt_properties_get_int( MLT_FILTER_PROPERTIES( this ), "deformY" );
98
99         // If there is an end adjust gain to the range
100         if ( mlt_properties_get( MLT_FILTER_PROPERTIES( this ), "end" ) != NULL )
101         {
102                 // Determine the time position of this frame in the transition duration
103                 mlt_position in = mlt_filter_get_in( this );
104                 mlt_position out = mlt_filter_get_out( this );
105                 mlt_position time = mlt_frame_get_position( frame );
106                 double position = ( double )( time - in ) / ( double )( out - in + 1 );
107                 double end = fabs( mlt_properties_get_double( MLT_FILTER_PROPERTIES( this ), "end" ) );
108                 wave += ( end - wave ) * position;
109         }
110
111         // Push the frame filter
112         mlt_properties_set_double( MLT_FRAME_PROPERTIES( frame ), "wave", wave );
113         mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "speed", speed );
114         mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "deformX", deformX );
115         mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "deformY", deformY );
116         mlt_frame_push_get_image( frame, filter_get_image );
117
118         return frame;
119 }
120
121 /** Constructor for the filter.
122 */
123
124 mlt_filter filter_wave_init( char *arg )
125 {
126         mlt_filter this = mlt_filter_new( );
127         if ( this != NULL )
128         {
129                 this->process = filter_process;
130                 mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "start", arg == NULL ? "10" : arg);
131                 mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "speed", arg == NULL ? "5" : arg);
132                 mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "deformX", arg == NULL ? "1" : arg);
133                 mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "deformY", arg == NULL ? "1" : arg);
134                 }
135         return this;
136 }
137
138
139