2 * wave.c -- wave filter
3 * Copyright (C) ?-2007 Leny Grisel <leny.grisel@laposte.net>
4 * Copyright (C) 2007 Jean-Baptiste Mardelle <jb@ader.ch>
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.
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.
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
21 #include <framework/mlt_filter.h>
22 #include <framework/mlt_frame.h>
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
)
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
];
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
)
41 int decalY
, decalX
, z
;
42 float amplitude
, phase
, pulsation
;
43 register int uneven
= src_w
% 2;
44 int w
= (src_w
- uneven
) / 2;
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;
51 decalY
= deformY ?
sin(pulsation
* x
* 2 + phase
) * amplitude
: 0;
53 *dst
++ = getPoint(src
, w
, src_h
, (x
+decalX
), (y
+decalY
), z
);
56 decalY
= sin(pulsation
* x
* 2 + phase
) * amplitude
;
58 *dst
++ = getPoint(src
, w
, src_h
, (x
+decalX
), (y
+decalY
), z
);
63 static int filter_get_image( mlt_frame
this, uint8_t **image
, mlt_image_format
*format
, int *width
, int *height
, int writable
)
66 int error
= mlt_frame_get_image( this, image
, format
, width
, height
, 1 );
67 mlt_position position
= mlt_frame_get_position( this );
69 // Only process if we have no error and a valid colour space
70 if ( error
== 0 && *format
== mlt_image_yuv422
)
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" );
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
);
88 /** Filter processing.
91 static mlt_frame
filter_process( mlt_filter
this, mlt_frame frame
)
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" );
99 // If there is an end adjust gain to the range
100 if ( mlt_properties_get( MLT_FILTER_PROPERTIES( this ), "end" ) != NULL
)
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
;
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
);
121 /** Constructor for the filter.
124 mlt_filter
filter_wave_init( mlt_profile profile
, mlt_service_type type
, const char *id
, char *arg
)
126 mlt_filter
this = mlt_filter_new( );
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
);