📄 erase.c
字号:
}/***************************************************************************** * FilterErase *****************************************************************************/static void FilterErase( filter_t *p_filter, picture_t *p_inpic, picture_t *p_outpic ){ filter_sys_t *p_sys = p_filter->p_sys; int i_plane; const int i_mask_pitch = p_sys->p_mask->A_PITCH; const int i_mask_visible_pitch = p_sys->p_mask->p[A_PLANE].i_visible_pitch; const int i_mask_visible_lines = p_sys->p_mask->p[A_PLANE].i_visible_lines; for( i_plane = 0; i_plane < p_inpic->i_planes; i_plane++ ) { const int i_pitch = p_inpic->p[i_plane].i_pitch; const int i_2pitch = i_pitch<<1; const int i_visible_pitch = p_inpic->p[i_plane].i_visible_pitch; const int i_lines = p_inpic->p[i_plane].i_lines; const int i_visible_lines = p_inpic->p[i_plane].i_visible_lines; uint8_t *p_inpix = p_inpic->p[i_plane].p_pixels; uint8_t *p_outpix = p_outpic->p[i_plane].p_pixels; uint8_t *p_mask = p_sys->p_mask->A_PIXELS; int i_x = p_sys->i_x, i_y = p_sys->i_y; int x, y; int i_height = i_mask_visible_lines; int i_width = i_mask_visible_pitch; const bool b_line_factor = ( i_plane /* U_PLANE or V_PLANE */ && !( p_inpic->format.i_chroma == VLC_FOURCC('I','4','2','2') || p_inpic->format.i_chroma == VLC_FOURCC('J','4','2','2') ) ); if( i_plane ) /* U_PLANE or V_PLANE */ { i_width >>= 1; i_x >>= 1; } if( b_line_factor ) { i_height >>= 1; i_y >>= 1; } i_height = __MIN( i_visible_lines - i_y, i_height ); i_width = __MIN( i_visible_pitch - i_x, i_width ); /* Copy original pixel buffer */ vlc_memcpy( p_outpix, p_inpix, i_pitch * i_lines ); /* Horizontal linear interpolation of masked areas */ p_outpix = p_outpic->p[i_plane].p_pixels + i_y*i_pitch + i_x; for( y = 0; y < i_height; y++, p_mask += i_mask_pitch, p_outpix += i_pitch ) { uint8_t prev, next = 0; int prev_x = -1, next_x = -2; int quot = 0; /* Find a suitable value for the previous color to use when * interpoling a masked pixel's value */ if( i_x ) { /* There are pixels before current position on the same line. * Use those */ prev = *(p_outpix-1); } else if( y || i_y ) { /* This is the first pixel on a line but there other lines * above us. Use the pixel right above */ prev = *(p_outpix-i_pitch); } else { /* We're in the upper left corner. This sucks. We can't use * any previous value, so we'll use a dummy one. In most * cases this dummy value will be fixed later on in the * algorithm */ prev = 0xff; } for( x = 0; x < i_width; x++ ) { if( p_mask[i_plane?x<<1:x] > 127 ) { /* This is a masked pixel */ if( next_x <= prev_x ) { int x0; /* Look for the next non masked pixel on the same * line (inside the mask's bounding box) */ for( x0 = x; x0 < i_width; x0++ ) { if( p_mask[i_plane?x0<<1:x0] <= 127 ) { /* We found an unmasked pixel. Victory! */ next_x = x0; next = p_outpix[x0]; break; } } if( next_x <= prev_x ) { /* We didn't find an unmasked pixel yet. Try * harder */ if( x0 == x ) x0++; if( x0 < i_visible_pitch ) { /* If we didn't find a non masked pixel on the * same line inside the mask's bounding box, * use the next pixel on the line (except if * it doesn't exist) */ next_x = x0; next = p_outpix[x0]; } else { /* The last pixel on the line is masked, * so we'll use the "prev" value. A better * approach would be to use unmasked pixels * at the end of adjacent lines */ next_x = x0; next = prev; } } if( !( i_x || y || i_y ) ) /* We were unable to find a suitable value for * the previous color (which means that we are * on the first line in the upper left corner) */ prev = next; /* Divide only once instead of next_x-prev_x-1 times */ quot = ((next-prev)<<16)/(next_x-prev_x); } /* Interpolate new value, and round correctly */ p_outpix[x] = prev + (((x-prev_x)*quot+(1<<16))>>16); } else { /* This pixel isn't masked. It's thus suitable as a * previous color for the next interpolation */ prev = p_outpix[x]; prev_x = x; } } } /* Vertical bluring */ p_mask = p_sys->p_mask->A_PIXELS; i_height = b_line_factor ? i_mask_visible_lines>>1 : i_mask_visible_lines; /* Make sure that we stop at least 2 lines before the picture's end * (since our bluring algorithm uses the 2 next lines) */ i_height = __MIN( i_visible_lines - i_y - 2, i_height ); /* Make sure that we start at least 2 lines from the top (since our * bluring algorithm uses the 2 previous lines) */ y = __MAX(i_y,2); p_outpix = p_outpic->p[i_plane].p_pixels + (i_y+y)*i_pitch + i_x; for( ; y < i_height; y++, p_mask += i_mask_pitch, p_outpix += i_pitch ) { for( x = 0; x < i_width; x++ ) { if( p_mask[i_plane?x<<1:x] > 127 ) { /* Ugly bluring function */ p_outpix[x] = ( (p_outpix[x-i_2pitch]<<1) /* 2 */ + (p_outpix[x-i_pitch ]<<2) /* 4 */ + (p_outpix[x ]<<2) /* 4 */ + (p_outpix[x+i_pitch ]<<2) /* 4 */ + (p_outpix[x+i_2pitch]<<1) )>>4; /* 2 */ } } } }}static int EraseCallback( vlc_object_t *p_this, char const *psz_var, vlc_value_t oldval, vlc_value_t newval, void *p_data ){ VLC_UNUSED(oldval); filter_sys_t *p_sys = (filter_sys_t *)p_data; if( !strcmp( psz_var, CFG_PREFIX "x" ) ) { vlc_mutex_lock( &p_sys->lock ); p_sys->i_x = newval.i_int; vlc_mutex_unlock( &p_sys->lock ); } else if( !strcmp( psz_var, CFG_PREFIX "y" ) ) { vlc_mutex_lock( &p_sys->lock ); p_sys->i_y = newval.i_int; vlc_mutex_unlock( &p_sys->lock ); } else if( !strcmp( psz_var, CFG_PREFIX "mask" ) ) { vlc_mutex_lock( &p_sys->lock ); LoadMask( (filter_t*)p_this, newval.psz_string ); vlc_mutex_unlock( &p_sys->lock ); } else { msg_Warn( p_this, "Unknown callback command." ); } return VLC_SUCCESS;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -