📄 distort.c
字号:
static void DistortWave( vout_thread_t *p_vout, picture_t *p_inpic, picture_t *p_outpic ){ int i_index; double f_angle; mtime_t new_date = mdate(); p_vout->p_sys->f_angle += (new_date - p_vout->p_sys->last_date) / 200000.0; p_vout->p_sys->last_date = new_date; f_angle = p_vout->p_sys->f_angle; for( i_index = 0 ; i_index < p_inpic->i_planes ; i_index++ ) { int i_line, i_num_lines, i_offset; uint8_t black_pixel; uint8_t *p_in, *p_out; p_in = p_inpic->p[i_index].p_pixels; p_out = p_outpic->p[i_index].p_pixels; i_num_lines = p_inpic->p[i_index].i_visible_lines; black_pixel = ( i_index == Y_PLANE ) ? 0x00 : 0x80; /* Ok, we do 3 times the sin() calculation for each line. So what ? */ for( i_line = 0 ; i_line < i_num_lines ; i_line++ ) { /* Calculate today's offset, don't go above 1/20th of the screen */ i_offset = (int)( (double)(p_inpic->p[i_index].i_visible_pitch) * sin( f_angle + 10.0 * (double)i_line / (double)i_num_lines ) / 20.0 ); if( i_offset ) { if( i_offset < 0 ) { p_vout->p_vlc->pf_memcpy( p_out, p_in - i_offset, p_inpic->p[i_index].i_visible_pitch + i_offset ); p_in += p_inpic->p[i_index].i_pitch; p_out += p_outpic->p[i_index].i_pitch; memset( p_out + i_offset, black_pixel, -i_offset ); } else { p_vout->p_vlc->pf_memcpy( p_out + i_offset, p_in, p_inpic->p[i_index].i_visible_pitch - i_offset ); memset( p_out, black_pixel, i_offset ); p_in += p_inpic->p[i_index].i_pitch; p_out += p_outpic->p[i_index].i_pitch; } } else { p_vout->p_vlc->pf_memcpy( p_out, p_in, p_inpic->p[i_index].i_visible_pitch ); p_in += p_inpic->p[i_index].i_pitch; p_out += p_outpic->p[i_index].i_pitch; } } }}/***************************************************************************** * DistortRipple: draw a ripple effect at the bottom of the picture *****************************************************************************/static void DistortRipple( vout_thread_t *p_vout, picture_t *p_inpic, picture_t *p_outpic ){ int i_index; double f_angle; mtime_t new_date = mdate(); p_vout->p_sys->f_angle -= (p_vout->p_sys->last_date - new_date) / 100000.0; p_vout->p_sys->last_date = new_date; f_angle = p_vout->p_sys->f_angle; for( i_index = 0 ; i_index < p_inpic->i_planes ; i_index++ ) { int i_line, i_first_line, i_num_lines, i_offset; uint8_t black_pixel; uint8_t *p_in, *p_out; black_pixel = ( i_index == Y_PLANE ) ? 0x00 : 0x80; i_num_lines = p_inpic->p[i_index].i_visible_lines; i_first_line = i_num_lines * 4 / 5; p_in = p_inpic->p[i_index].p_pixels; p_out = p_outpic->p[i_index].p_pixels; for( i_line = 0 ; i_line < i_first_line ; i_line++ ) { p_vout->p_vlc->pf_memcpy( p_out, p_in, p_inpic->p[i_index].i_visible_pitch ); p_in += p_inpic->p[i_index].i_pitch; p_out += p_outpic->p[i_index].i_pitch; } /* Ok, we do 3 times the sin() calculation for each line. So what ? */ for( i_line = i_first_line ; i_line < i_num_lines ; i_line++ ) { /* Calculate today's offset, don't go above 1/20th of the screen */ i_offset = (int)( (double)(p_inpic->p[i_index].i_pitch) * sin( f_angle + 2.0 * (double)i_line / (double)( 1 + i_line - i_first_line) ) * (double)(i_line - i_first_line) / (double)i_num_lines / 8.0 ); if( i_offset ) { if( i_offset < 0 ) { p_vout->p_vlc->pf_memcpy( p_out, p_in - i_offset, p_inpic->p[i_index].i_visible_pitch + i_offset ); p_in -= p_inpic->p[i_index].i_pitch; p_out += p_outpic->p[i_index].i_pitch; memset( p_out + i_offset, black_pixel, -i_offset ); } else { p_vout->p_vlc->pf_memcpy( p_out + i_offset, p_in, p_inpic->p[i_index].i_visible_pitch - i_offset ); memset( p_out, black_pixel, i_offset ); p_in -= p_inpic->p[i_index].i_pitch; p_out += p_outpic->p[i_index].i_pitch; } } else { p_vout->p_vlc->pf_memcpy( p_out, p_in, p_inpic->p[i_index].i_visible_pitch ); p_in -= p_inpic->p[i_index].i_pitch; p_out += p_outpic->p[i_index].i_pitch; } } }}/***************************************************************************** * Gaussian Convolution ***************************************************************************** * Gaussian convolution ( sigma == 1.4 ) * * | 2 4 5 4 2 | | 2 4 4 4 2 | * | 4 9 12 9 4 | | 4 8 12 8 4 | * | 5 12 15 12 5 | ~ | 4 12 16 12 4 | * | 4 9 12 9 4 | | 4 8 12 8 4 | * | 2 4 5 4 2 | | 2 4 4 4 2 | *****************************************************************************/static void GaussianConvolution( picture_t *p_inpic, uint32_t *p_smooth ){ uint8_t *p_inpix = p_inpic->p[Y_PLANE].p_pixels; int i_src_pitch = p_inpic->p[Y_PLANE].i_pitch; int i_src_visible = p_inpic->p[Y_PLANE].i_visible_pitch; int i_num_lines = p_inpic->p[Y_PLANE].i_visible_lines; int x,y; for( y = 2; y < i_num_lines - 2; y++ ) { for( x = 2; x < i_src_visible - 2; x++ ) { p_smooth[y*i_src_visible+x] = (uint32_t)( /* 2 rows up */ ( p_inpix[(y-2)*i_src_pitch+x-2]<<1 ) + ( p_inpix[(y-2)*i_src_pitch+x-1]<<2 ) + ( p_inpix[(y-2)*i_src_pitch+x]<<2 ) + ( p_inpix[(y-2)*i_src_pitch+x+1]<<2 ) + ( p_inpix[(y-2)*i_src_pitch+x+2]<<1 ) /* 1 row up */ + ( p_inpix[(y-1)*i_src_pitch+x-2]<<2 ) + ( p_inpix[(y-1)*i_src_pitch+x-1]<<3 ) + ( p_inpix[(y-1)*i_src_pitch+x]*12 ) + ( p_inpix[(y-1)*i_src_pitch+x+1]<<3 ) + ( p_inpix[(y-1)*i_src_pitch+x+2]<<2 ) /* */ + ( p_inpix[y*i_src_pitch+x-2]<<2 ) + ( p_inpix[y*i_src_pitch+x-1]*12 ) + ( p_inpix[y*i_src_pitch+x]<<4 ) + ( p_inpix[y*i_src_pitch+x+1]*12 ) + ( p_inpix[y*i_src_pitch+x+2]<<2 ) /* 1 row down */ + ( p_inpix[(y+1)*i_src_pitch+x-2]<<2 ) + ( p_inpix[(y+1)*i_src_pitch+x-1]<<3 ) + ( p_inpix[(y+1)*i_src_pitch+x]*12 ) + ( p_inpix[(y+1)*i_src_pitch+x+1]<<3 ) + ( p_inpix[(y+1)*i_src_pitch+x+2]<<2 ) /* 2 rows down */ + ( p_inpix[(y+2)*i_src_pitch+x-2]<<1 ) + ( p_inpix[(y+2)*i_src_pitch+x-1]<<2 ) + ( p_inpix[(y+2)*i_src_pitch+x]<<2 ) + ( p_inpix[(y+2)*i_src_pitch+x+1]<<2 ) + ( p_inpix[(y+2)*i_src_pitch+x+2]<<1 ) ) >> 7 /* 115 */; } }}/***************************************************************************** * DistortGradient: Sobel *****************************************************************************/static void DistortGradient( vout_thread_t *p_vout, picture_t *p_inpic, picture_t *p_outpic ){ int x, y; int i_src_pitch = p_inpic->p[Y_PLANE].i_pitch; int i_src_visible = p_inpic->p[Y_PLANE].i_visible_pitch; int i_dst_pitch = p_outpic->p[Y_PLANE].i_pitch; int i_num_lines = p_inpic->p[Y_PLANE].i_visible_lines; uint8_t *p_inpix = p_inpic->p[Y_PLANE].p_pixels; uint8_t *p_outpix = p_outpic->p[Y_PLANE].p_pixels; uint32_t *p_smooth = (uint32_t *)malloc( i_num_lines * i_src_visible * sizeof(uint32_t)); if( !p_smooth ) return; if( p_vout->p_sys->b_cartoon ) { p_vout->p_vlc->pf_memcpy( p_outpic->p[U_PLANE].p_pixels, p_inpic->p[U_PLANE].p_pixels, p_outpic->p[U_PLANE].i_lines * p_outpic->p[U_PLANE].i_pitch ); p_vout->p_vlc->pf_memcpy( p_outpic->p[V_PLANE].p_pixels, p_inpic->p[V_PLANE].p_pixels, p_outpic->p[V_PLANE].i_lines * p_outpic->p[V_PLANE].i_pitch ); } else { p_vout->p_vlc->pf_memset( p_outpic->p[U_PLANE].p_pixels, 0x80, p_outpic->p[U_PLANE].i_lines * p_outpic->p[U_PLANE].i_pitch ); p_vout->p_vlc->pf_memset( p_outpic->p[V_PLANE].p_pixels, 0x80, p_outpic->p[V_PLANE].i_lines * p_outpic->p[V_PLANE].i_pitch ); } GaussianConvolution( p_inpic, p_smooth ); /* Sobel gradient | -1 0 1 | | 1 2 1 | | -2 0 2 | and | 0 0 0 | | -1 0 1 | | -1 -2 -1 | */ for( y = 1; y < i_num_lines - 1; y++ ) { for( x = 1; x < i_src_visible - 1; x++ ) { uint32_t a = ( abs( ( ( p_smooth[(y-1)*i_src_visible+x] - p_smooth[(y+1)*i_src_visible+x] ) <<1 ) + ( p_smooth[(y-1)*i_src_visible+x-1] - p_smooth[(y+1)*i_src_visible+x-1] ) + ( p_smooth[(y-1)*i_src_visible+x+1] - p_smooth[(y+1)*i_src_visible+x+1] ) ) + abs( ( ( p_smooth[y*i_src_visible+x-1] - p_smooth[y*i_src_visible+x+1] ) <<1 ) + ( p_smooth[(y-1)*i_src_visible+x-1] - p_smooth[(y-1)*i_src_visible+x+1] ) + ( p_smooth[(y+1)*i_src_visible+x-1] - p_smooth[(y+1)*i_src_visible+x+1] ) ) ); if( p_vout->p_sys->i_gradient_type ) { if( p_vout->p_sys->b_cartoon ) { if( a > 60 ) { p_outpix[y*i_dst_pitch+x] = 0x00; } else { if( p_smooth[y*i_src_visible+x] > 0xa0 ) p_outpix[y*i_dst_pitch+x] = 0xff - ((0xff - p_inpix[y*i_src_pitch+x] )>>2); else if( p_smooth[y*i_src_visible+x] > 0x70 ) p_outpix[y*i_dst_pitch+x] = 0xa0 - ((0xa0 - p_inpix[y*i_src_pitch+x] )>>2); else if( p_smooth[y*i_src_visible+x] > 0x28 ) p_outpix[y*i_dst_pitch+x] = 0x70 - ((0x70 - p_inpix[y*i_src_pitch+x] )>>2); else p_outpix[y*i_dst_pitch+x] = 0x28 - ((0x28 - p_inpix[y*i_src_pitch+x] )>>2); } } else { if( a>>8 ) p_outpix[y*i_dst_pitch+x] = 255; else p_outpix[y*i_dst_pitch+x] = (uint8_t)a; } } else { if( a>>8 ) p_outpix[y*i_dst_pitch+x] = 0; else p_outpix[y*i_dst_pitch+x] = (uint8_t)(255 - a); } } } if( p_smooth ) free( p_smooth );}/***************************************************************************** * DistortEdge: Canny edge detection algorithm ***************************************************************************** * http://fourier.eng.hmc.edu/e161/lectures/canny/node1.html * (well ... my implementation isn't really the canny algorithm ... but some * ideas are the same) *****************************************************************************//* angle : | */#define THETA_Y 0/* angle : - */#define THETA_X 1/* angle : / */#define THETA_P 2/* angle : \ */#define THETA_M 3static void DistortEdge( vout_thread_t *p_vout, picture_t *p_inpic, picture_t *p_outpic ){ int x, y; int i_src_pitch = p_inpic->p[Y_PLANE].i_pitch; int i_src_visible = p_inpic->p[Y_PLANE].i_visible_pitch; int i_dst_pitch = p_outpic->p[Y_PLANE].i_pitch; int i_num_lines = p_inpic->p[Y_PLANE].i_visible_lines; uint8_t *p_inpix = p_inpic->p[Y_PLANE].p_pixels; uint8_t *p_outpix = p_outpic->p[Y_PLANE].p_pixels; uint32_t *p_smooth = malloc( i_num_lines*i_src_visible * sizeof(uint32_t) ); uint32_t *p_grad = malloc( i_num_lines*i_src_visible *sizeof(uint32_t) ); uint8_t *p_theta = malloc( i_num_lines*i_src_visible *sizeof(uint8_t) ); if( !p_smooth || !p_grad || !p_theta ) return; if( p_vout->p_sys->b_cartoon ) { p_vout->p_vlc->pf_memcpy( p_outpic->p[U_PLANE].p_pixels, p_inpic->p[U_PLANE].p_pixels, p_outpic->p[U_PLANE].i_lines * p_outpic->p[U_PLANE].i_pitch ); p_vout->p_vlc->pf_memcpy( p_outpic->p[V_PLANE].p_pixels, p_inpic->p[V_PLANE].p_pixels, p_outpic->p[V_PLANE].i_lines * p_outpic->p[V_PLANE].i_pitch ); } else { p_vout->p_vlc->pf_memset( p_outpic->p[Y_PLANE].p_pixels, 0xff, p_outpic->p[Y_PLANE].i_lines * p_outpic->p[Y_PLANE].i_pitch ); p_vout->p_vlc->pf_memset( p_outpic->p[U_PLANE].p_pixels, 0x80, p_outpic->p[U_PLANE].i_lines * p_outpic->p[U_PLANE].i_pitch ); memset( p_outpic->p[V_PLANE].p_pixels, 0x80, p_outpic->p[V_PLANE].i_lines * p_outpic->p[V_PLANE].i_pitch ); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -