Cleanup copyrights and attributions, and move Jean-Baptiste's services to a new kdenl...
[melted] / 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