/* * filter_dust.c -- dust filter * Copyright (c) 2007 Marco Gittler * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ //#include //#include #include #include #include #include #include #include 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=0 && (y-ypos)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 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 im=rand()%maxcount; 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; 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: *pix-=(*pix)*v; break; case 1: *pix+=(255-*pix)*v; break; } } } } } return error; } static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) { mlt_frame_push_service( frame, this ); mlt_frame_push_get_image( frame, filter_get_image ); return frame; } mlt_filter filter_dust_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) { mlt_filter this = mlt_filter_new( ); if ( this != NULL ) { this->process = filter_process; mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "maxdiameter", "2" ); mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "maxcount", "10" ); } return this; }