Merge ../mlt
[melted] / src / modules / oldfilm / filter_dust.c
index c133813..fc62024 100644 (file)
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#include <framework/mlt_filter.h>
-#include <framework/mlt_frame.h>
+//#include <framework/mlt_filter.h>
+//#include <framework/mlt_frame.h>
+#include <framework/mlt.h>
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <math.h>
+#include <string.h>
+#include <time.h>
 
+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 ){
+       int x,y;
+
+       for (y=ypos;y<src_height ; y++){
+               if ( y>=0 && (y-ypos)<overlay_height ){
+                       uint8_t *scanline_image=src+src_width*y*2;
+                       int overlay_y = upsidedown ?  ( overlay_height - ( y - ypos ) - 1 ) : ( y - ypos  );
+                       uint8_t *scanline_overlay=overlay + overlay_width * 2 * overlay_y;
+                       
+                       for ( x = xpos  ;  x < src_width  && x-xpos < overlay_width ;x++){
+                               if ( x>0  ){
+                                       int overlay_x = mirror ? overlay_width - ( x - xpos ) -1 : ( x - xpos );
+                                       double alp=(double)*(alpha+ overlay_width * overlay_y + overlay_x )/255.0;
+                                       uint8_t* image_pixel = scanline_image + x * 2;
+                                       uint8_t* overlay_pixel = scanline_overlay + overlay_x * 2;
+                                       
+                                       *image_pixel=(double)(*overlay_pixel)*alp+ (double)*image_pixel*(1.0-alp) ;
+                                       if (xpos%2==0)
+                                               image_pixel++;
+                                       else
+                                               image_pixel+=3;
+
+                                       mirror? overlay_pixel-- : overlay_pixel++;
+
+                                       *image_pixel=(double)(*(overlay_pixel))*alp + (double)(*image_pixel )*(1.0-alp) ;
+                               }
+               
+                       }
+               }
+       }
+}
 
 static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable )
 {
-
        mlt_filter filter = mlt_frame_pop_service( this );
-       int error = mlt_frame_get_image( this, image, format, width, height, 1 );
+       
+       int maxdia = mlt_properties_get_int( MLT_FILTER_PROPERTIES( filter ), "maxdiameter" );
+       int maxcount = mlt_properties_get_int( MLT_FILTER_PROPERTIES( filter ), "maxcount" );
 
+       mlt_position in = mlt_filter_get_in( filter );
+       mlt_position out = mlt_filter_get_out( filter );
+       mlt_position time = mlt_frame_get_position( this );
+       double position = ( double )( time - in ) / ( double )( out - in + 1 );
+
+       int error = mlt_frame_get_image( this, image, format, width, height, 1 );       
+       // load svg
+       mlt_properties properties = MLT_FILTER_PROPERTIES( filter );
+       char *factory = mlt_properties_get( properties, "factory" );
+       char temp[1204]="";
+       sprintf( temp, "%s/oldfilm/", mlt_environment( "MLT_DATA" ) );
+       
+       mlt_properties direntries=mlt_properties_new();
+       mlt_properties_dir_list(direntries,temp,"dust*.svg",1);
+       
+       if (!maxcount)
+               return 0;
+       srand(position*10000);
+
+       int im=rand()%maxcount;
+       int piccount=mlt_properties_count(direntries);
+       while (im-- && piccount){
+       
+               int picnum=rand()%piccount;
+               
+               int y1=rand()%*height;
+               int x1=rand()%*width;
+               char resource[1024]="";
+               char savename[1024]="",savename1[1024]="", cachedy[100];
+               int dx=(*width*maxdia/100);
+               int luma_width,luma_height;
+               uint8_t *luma_image = NULL;
+               uint8_t *alpha =NULL;
+               int updown= rand()%2;
+               int mirror=rand()%2;
+               
+               sprintf(resource,"%s",mlt_properties_get_value(direntries,picnum));
+               sprintf(savename,"cache-%d-%d",picnum,dx);
+               sprintf(savename1,"cache-alpha-%d-%d",picnum,dx);
+               sprintf(cachedy,"cache-dy-%d-%d",picnum,dx);
+               
+               luma_image= mlt_properties_get_data( properties , savename , NULL );
+               alpha= mlt_properties_get_data( properties , savename1 , NULL );
+               
+               if (luma_image == NULL || alpha == NULL ){
+                       mlt_profile profile = mlt_service_profile( MLT_FILTER_SERVICE( filter ) );
+                       mlt_producer producer = mlt_factory_producer( profile, factory, resource );
+               
+                       if ( producer != NULL )
+                       {
+                               mlt_properties producer_properties = MLT_PRODUCER_PROPERTIES( producer );
+                               
+                               mlt_properties_set( producer_properties, "eof", "loop" );
+                               mlt_frame luma_frame = NULL;
+                               
+                               if ( mlt_service_get_frame( MLT_PRODUCER_SERVICE( producer ), &luma_frame, 0 ) == 0 ){
+               
+                                       mlt_properties_set_double ( MLT_FRAME_PROPERTIES ( luma_frame ) , "consumer_aspect_ratio" , 1.0 );
+                                       mlt_image_format luma_format = mlt_image_yuv422;
+                                       luma_width = dx;
+                                       luma_height = luma_width * mlt_properties_get_int( MLT_FRAME_PROPERTIES ( luma_frame ) , "height" ) / mlt_properties_get_int( MLT_FRAME_PROPERTIES ( luma_frame ) , "width" );
+
+                                       mlt_properties_set( MLT_FRAME_PROPERTIES( luma_frame ), "rescale.interp", "best" );// none/nearest/tiles/hyper
+                                       
+                                       mlt_frame_get_image( luma_frame, &luma_image, &luma_format, &luma_width, &luma_height, 0 );
+                                       alpha =mlt_frame_get_alpha_mask(luma_frame);
+                                       
+                                       uint8_t* savealpha=mlt_pool_alloc ( luma_width * luma_height );
+                                       uint8_t* savepic=mlt_pool_alloc ( luma_width * luma_height * 2);
+                                       
+                                       if (savealpha && savepic ){
+                                               memcpy (savealpha, alpha , luma_width * luma_height );
+                                               memcpy (savepic, luma_image , luma_width * luma_height * 2);
+                                               
+                                               mlt_properties_set_data ( properties , savename , savepic , sizeof(uint8_t*) , mlt_pool_release, NULL );
+                                               mlt_properties_set_data ( properties , savename1 , savealpha , sizeof(uint8_t*)  ,  mlt_pool_release, NULL );
+                                               mlt_properties_set_int ( properties , cachedy , luma_height );
+                                               
+                                               overlay_image(*image,*width,*height,luma_image,luma_width,luma_height, alpha, x1, y1 , updown , mirror );
+                                       }
+                                       mlt_frame_close( luma_frame );  
+                               }
+                               mlt_producer_close( producer ); 
+                       }
+               }else {
+                       overlay_image ( *image , *width, *height , luma_image , dx , mlt_properties_get_int ( properties , cachedy ) , alpha , x1 , y1 , updown , mirror );
+               }
+       }
+       if (piccount>0 )
+               return 0;
        if ( error == 0 && *image && *format == mlt_image_yuv422 )
        {
 
                int h = *height;
                int w = *width;
+               if (maxcount==0)
+                       return 0;
 
-               int maxdia = mlt_properties_get_int( MLT_FILTER_PROPERTIES( filter ), "maxdiameter" );
-               int maxcount = mlt_properties_get_int( MLT_FILTER_PROPERTIES( filter ), "maxcount" );
                int im=rand()%maxcount;
                
-               while (im--){
+               while (im-- ){
                        int type=im%2;
                        int y1=rand()%h;
                        int x1=rand()%w;
                        int dx=rand()%maxdia;
                        int dy=rand()%maxdia;
                        int x=0,y=0;//,v=0;
-                       for (x=-dx;x<dx;x++)
-                               for (y=-dy;y<dy;y++){
-                                       if (x1+x<w && x1+x>0 && y1+y<h && y1+y>0 && x!=0 && y!=0){
-                                               //uint8_t *pix=*image+(y+y1)*w*2+(x+x1)*2;
-                                               //v=255*(abs(x)+abs(y))/dx;
+                       double v=0.0;
+                       for ( x = -dx ; x < dx ; x++ )
+                               for ( y = -dy ; y < dy ; y++ ) {
+                                       if ( x1+x < w && x1+x > 0 && y1+y < h && y1+y > 0 ){
+                                               uint8_t *pix=*image+(y+y1)*w*2+(x+x1)*2;
+                                               //v=(1.0-fabs(x)/dx)*(1.0-fabs(y)/dy);
+                                               v=pow((double)x/(double)dx*5.0,2.0)+pow((double)y/(double)dy*5.0,2.0);
+                                               if (v>10)
+                                                       v=10;
+                                               v=1.0-(v/10.0);
+
                                                switch(type){
                                                        case 0:
-                                                               //v=((51*sqrt(y*y+x*x))/255);
-                                                               *(*image+(y+y1)*w*2+(x+x1)*2)=*(*image+(y+y1)*w*2+(x+x1)*2)/((51*sqrt(y*y+x*x))/255);
-                                                               /*if (v!=0)
-                                                                       *pix/=v;
-                                                               else
-                                                                       *pix=0;*/
+                                                               *pix-=(*pix)*v;
                                                                break;
                                                        case 1:
-                                                               //v=((51*sqrt(y*y+x*x))/255);
-                                                               //v=255*(x+y)/dx;
-                                                               *(*image+(y+y1)*w*2+(x+x1)*2)=*(*image+(y+y1)*w*2+(x+x1)*2)*((51*sqrt(y*y+x*x))/255);
-                                                               /*if ((*pix*v)<255)
-                                                                       *pix*=v;
-                                                               else
-                                                                       *pix=255;*/
+                                                               *pix+=(255-*pix)*v;
                                                                break;
                                                }
                                        }
@@ -95,7 +215,7 @@ mlt_filter filter_dust_init( mlt_profile profile, mlt_service_type type, const c
        if ( this != NULL )
        {
                this->process = filter_process;
-               mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "maxdiameter", "10" );
+               mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "maxdiameter", "2" );
                mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "maxcount", "10" );
        }
        return this;