]> git.sesse.net Git - mlt/blob - src/modules/oldfilm/filter_dust.c
Refactor to mlt_filter_get_progress().
[mlt] / src / modules / oldfilm / filter_dust.c
1 /*
2  * filter_dust.c -- dust filter
3  * Copyright (c) 2007 Marco Gittler <g.marco@freenet.de>
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 <framework/mlt_filter.h>
21 //#include <framework/mlt_frame.h>
22 #include <framework/mlt.h>
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <math.h>
27 #include <string.h>
28 #include <time.h>
29
30 static void overlay_image(uint8_t *src, int src_width, int src_height , uint8_t * overlay, int overlay_width, int overlay_height, uint8_t * alpha , int xpos, int ypos, int upsidedown , int mirror ){
31         int x,y;
32
33         for (y=ypos;y<src_height ; y++){
34                 if ( y>=0 && (y-ypos)<overlay_height ){
35                         uint8_t *scanline_image=src+src_width*y*2;
36                         int overlay_y = upsidedown ?  ( overlay_height - ( y - ypos ) - 1 ) : ( y - ypos  );
37                         uint8_t *scanline_overlay=overlay + overlay_width * 2 * overlay_y;
38                         
39                         for ( x = xpos  ;  x < src_width  && x-xpos < overlay_width ;x++){
40                                 if ( x>0  ){
41                                         int overlay_x = mirror ? overlay_width - ( x - xpos ) -1 : ( x - xpos );
42                                         double alp=(double)*(alpha+ overlay_width * overlay_y + overlay_x )/255.0;
43                                         uint8_t* image_pixel = scanline_image + x * 2;
44                                         uint8_t* overlay_pixel = scanline_overlay + overlay_x * 2;
45                                         
46                                         *image_pixel=(double)(*overlay_pixel)*alp+ (double)*image_pixel*(1.0-alp) ;
47                                         if (xpos%2==0)
48                                                 image_pixel++;
49                                         else
50                                                 image_pixel+=3;
51
52                                         mirror? overlay_pixel-- : overlay_pixel++;
53
54                                         *image_pixel=(double)(*(overlay_pixel))*alp + (double)(*image_pixel )*(1.0-alp) ;
55                                 }
56                 
57                         }
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         mlt_filter filter = mlt_frame_pop_service( this );
65         
66         int maxdia = mlt_properties_get_int( MLT_FILTER_PROPERTIES( filter ), "maxdiameter" );
67         int maxcount = mlt_properties_get_int( MLT_FILTER_PROPERTIES( filter ), "maxcount" );
68
69         *format = mlt_image_yuv422;
70         int error = mlt_frame_get_image( this, image, format, width, height, 1 );       
71         // load svg
72         mlt_properties properties = MLT_FILTER_PROPERTIES( filter );
73         char *factory = mlt_properties_get( properties, "factory" );
74         char temp[1204]="";
75         sprintf( temp, "%s/oldfilm/", mlt_environment( "MLT_DATA" ) );
76         
77         mlt_properties direntries=mlt_properties_new();
78         mlt_properties_dir_list(direntries,temp,"dust*.svg",1);
79         
80         if (!maxcount)
81                 return 0;
82
83         double position = mlt_filter_get_progress( filter, this );
84         srand(position*10000);
85
86         mlt_service_lock( MLT_FILTER_SERVICE( filter ) );
87
88         int im=rand()%maxcount;
89         int piccount=mlt_properties_count(direntries);
90         while (im-- && piccount){
91         
92                 int picnum=rand()%piccount;
93                 
94                 int y1=rand()%*height;
95                 int x1=rand()%*width;
96                 char resource[1024]="";
97                 char savename[1024]="",savename1[1024]="", cachedy[100];
98                 int dx=(*width*maxdia/100);
99                 int luma_width,luma_height;
100                 uint8_t *luma_image = NULL;
101                 uint8_t *alpha =NULL;
102                 int updown= rand()%2;
103                 int mirror=rand()%2;
104                 
105                 sprintf(resource,"%s",mlt_properties_get_value(direntries,picnum));
106                 sprintf(savename,"cache-%d-%d",picnum,dx);
107                 sprintf(savename1,"cache-alpha-%d-%d",picnum,dx);
108                 sprintf(cachedy,"cache-dy-%d-%d",picnum,dx);
109                 
110                 luma_image= mlt_properties_get_data( properties , savename , NULL );
111                 alpha= mlt_properties_get_data( properties , savename1 , NULL );
112                 
113                 if (luma_image == NULL || alpha == NULL ){
114                         mlt_profile profile = mlt_service_profile( MLT_FILTER_SERVICE( filter ) );
115                         mlt_producer producer = mlt_factory_producer( profile, factory, resource );
116                 
117                         if ( producer != NULL )
118                         {
119                                 mlt_properties producer_properties = MLT_PRODUCER_PROPERTIES( producer );
120                                 
121                                 mlt_properties_set( producer_properties, "eof", "loop" );
122                                 mlt_frame luma_frame = NULL;
123                                 
124                                 if ( mlt_service_get_frame( MLT_PRODUCER_SERVICE( producer ), &luma_frame, 0 ) == 0 ){
125                 
126                                         mlt_properties_set_double ( MLT_FRAME_PROPERTIES ( luma_frame ) , "consumer_aspect_ratio" , 1.0 );
127                                         mlt_image_format luma_format = mlt_image_yuv422;
128                                         luma_width = dx;
129                                         luma_height = luma_width * mlt_properties_get_int( MLT_FRAME_PROPERTIES ( luma_frame ) , "height" ) / mlt_properties_get_int( MLT_FRAME_PROPERTIES ( luma_frame ) , "width" );
130
131                                         mlt_properties_set( MLT_FRAME_PROPERTIES( luma_frame ), "rescale.interp", "best" );// none/nearest/tiles/hyper
132                                         
133                                         mlt_frame_get_image( luma_frame, &luma_image, &luma_format, &luma_width, &luma_height, 0 );
134                                         alpha =mlt_frame_get_alpha_mask(luma_frame);
135                                         
136                                         uint8_t* savealpha=mlt_pool_alloc ( luma_width * luma_height );
137                                         uint8_t* savepic=mlt_pool_alloc ( luma_width * luma_height * 2);
138                                         
139                                         if (savealpha && savepic ){
140                                                 memcpy (savealpha, alpha , luma_width * luma_height );
141                                                 memcpy (savepic, luma_image , luma_width * luma_height * 2);
142                                                 
143                                                 mlt_properties_set_data ( properties , savename , savepic , sizeof(uint8_t*) , mlt_pool_release, NULL );
144                                                 mlt_properties_set_data ( properties , savename1 , savealpha , sizeof(uint8_t*)  ,  mlt_pool_release, NULL );
145                                                 mlt_properties_set_int ( properties , cachedy , luma_height );
146                                                 
147                                                 overlay_image(*image,*width,*height,luma_image,luma_width,luma_height, alpha, x1, y1 , updown , mirror );
148                                         }
149                                         mlt_frame_close( luma_frame );  
150                                 }
151                                 mlt_producer_close( producer ); 
152                         }
153                 }else {
154                         overlay_image ( *image , *width, *height , luma_image , dx , mlt_properties_get_int ( properties , cachedy ) , alpha , x1 , y1 , updown , mirror );
155                 }
156         }
157
158         mlt_service_unlock( MLT_FILTER_SERVICE( filter ) );
159
160         if (piccount>0 )
161                 return 0;
162         if ( error == 0 && *image )
163         {
164
165                 int h = *height;
166                 int w = *width;
167                 if (maxcount==0)
168                         return 0;
169
170                 int im=rand()%maxcount;
171                 
172                 while (im-- ){
173                         int type=im%2;
174                         int y1=rand()%h;
175                         int x1=rand()%w;
176                         int dx=rand()%maxdia;
177                         int dy=rand()%maxdia;
178                         int x=0,y=0;//,v=0;
179                         double v=0.0;
180                         for ( x = -dx ; x < dx ; x++ )
181                                 for ( y = -dy ; y < dy ; y++ ) {
182                                         if ( x1+x < w && x1+x > 0 && y1+y < h && y1+y > 0 ){
183                                                 uint8_t *pix=*image+(y+y1)*w*2+(x+x1)*2;
184                                                 //v=(1.0-fabs(x)/dx)*(1.0-fabs(y)/dy);
185                                                 v=pow((double)x/(double)dx*5.0,2.0)+pow((double)y/(double)dy*5.0,2.0);
186                                                 if (v>10)
187                                                         v=10;
188                                                 v=1.0-(v/10.0);
189
190                                                 switch(type){
191                                                         case 0:
192                                                                 *pix-=(*pix)*v;
193                                                                 break;
194                                                         case 1:
195                                                                 *pix+=(255-*pix)*v;
196                                                                 break;
197                                                 }
198                                         }
199                                 }
200                 }
201         }
202
203         return error;
204 }
205
206 static mlt_frame filter_process( mlt_filter this, mlt_frame frame )
207 {
208
209         mlt_frame_push_service( frame, this );
210         mlt_frame_push_get_image( frame, filter_get_image );
211         return frame;
212 }
213
214
215 mlt_filter filter_dust_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
216 {
217         mlt_filter this = mlt_filter_new( );
218         if ( this != NULL )
219         {
220                 this->process = filter_process;
221                 mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "maxdiameter", "2" );
222                 mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "maxcount", "10" );
223         }
224         return this;
225 }
226
227