mirror of
https://code.videolan.org/videolan/vlc
synced 2024-10-03 01:31:53 +02:00
codec: libass: speed up C blending, as for freetype
This commit is contained in:
parent
ffb4a94e2b
commit
296e18b19c
@ -696,49 +696,65 @@ static void RegionDraw( subpicture_region_t *p_region, ASS_Image *p_img )
|
||||
const int i_width = p_region->fmt.i_width;
|
||||
const int i_height = p_region->fmt.i_height;
|
||||
|
||||
memset( p->p_pixels, 0x00, p->i_pitch * p->i_lines );
|
||||
memset( p->p_pixels, 0x00, p->i_pitch * p->i_visible_lines );
|
||||
for( ; p_img != NULL; p_img = p_img->next )
|
||||
{
|
||||
if( p_img->dst_x < i_x || p_img->dst_x + p_img->w > i_x + i_width ||
|
||||
p_img->dst_y < i_y || p_img->dst_y + p_img->h > i_y + i_height )
|
||||
int i_dst_x = p_img->dst_x - i_x;
|
||||
int i_dst_y = p_img->dst_y - i_y;
|
||||
if( i_dst_x < 0 || i_dst_x + p_img->w > i_width ||
|
||||
i_dst_y < 0 || i_dst_y + p_img->h > i_height )
|
||||
continue;
|
||||
|
||||
/* /!\ Bogus alpha channel is inverted */
|
||||
const unsigned a = (~p_img->color )&0xff;
|
||||
if( a == 0 )
|
||||
continue;
|
||||
|
||||
const unsigned r = (p_img->color >> 24)&0xff;
|
||||
const unsigned g = (p_img->color >> 16)&0xff;
|
||||
const unsigned b = (p_img->color >> 8)&0xff;
|
||||
const unsigned a = (p_img->color )&0xff;
|
||||
int x, y;
|
||||
|
||||
for( y = 0; y < p_img->h; y++ )
|
||||
const uint8_t *srcrow = p_img->bitmap;
|
||||
int i_pitch_src = p_img->stride;
|
||||
int i_pitch_dst = p->i_pitch;
|
||||
uint8_t *dstrow = &p->p_pixels[i_dst_y * i_pitch_dst + 4 * i_dst_x];
|
||||
|
||||
for( int y = 0; y < p_img->h; y++ )
|
||||
{
|
||||
for( x = 0; x < p_img->w; x++ )
|
||||
const uint8_t *src = srcrow;
|
||||
uint8_t *dst = dstrow;
|
||||
|
||||
for( int x = 0; x < p_img->w; x++ )
|
||||
{
|
||||
const unsigned alpha = p_img->bitmap[y*p_img->stride+x];
|
||||
const unsigned an = (255 - a) * alpha / 255;
|
||||
|
||||
uint8_t *p_rgba = &p->p_pixels[(y+p_img->dst_y-i_y) * p->i_pitch + 4 * (x+p_img->dst_x-i_x)];
|
||||
const unsigned ao = p_rgba[3];
|
||||
|
||||
/* Native endianness, but RGBA ordering */
|
||||
if( ao == 0 )
|
||||
unsigned opacity = *src++; /* 1 Bpp channel */
|
||||
if( opacity != 0 ) /* we need to blend only non transparent content */
|
||||
{
|
||||
/* Optimized but the else{} will produce the same result */
|
||||
p_rgba[0] = r;
|
||||
p_rgba[1] = g;
|
||||
p_rgba[2] = b;
|
||||
p_rgba[3] = an;
|
||||
}
|
||||
else
|
||||
{
|
||||
p_rgba[3] = 255 - ( 255 - p_rgba[3] ) * ( 255 - an ) / 255;
|
||||
if( p_rgba[3] != 0 )
|
||||
unsigned i_an = a * opacity / 255U;
|
||||
unsigned i_ao = dst[3];
|
||||
if( i_ao == 0 )
|
||||
{
|
||||
p_rgba[0] = ( p_rgba[0] * ao * (255-an) / 255 + r * an ) / p_rgba[3];
|
||||
p_rgba[1] = ( p_rgba[1] * ao * (255-an) / 255 + g * an ) / p_rgba[3];
|
||||
p_rgba[2] = ( p_rgba[2] * ao * (255-an) / 255 + b * an ) / p_rgba[3];
|
||||
dst[0] = r;
|
||||
dst[1] = g;
|
||||
dst[2] = b;
|
||||
dst[3] = i_an;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned i_ani = 255 - i_an;
|
||||
dst[3] = 255 - (255 - i_ao) * i_ani / 255;
|
||||
if( dst[3] != 0 )
|
||||
{
|
||||
unsigned i_aoni = i_ao * i_ani / 255;
|
||||
dst[0] = ( dst[0] * i_aoni + r * i_an ) / dst[3];
|
||||
dst[1] = ( dst[1] * i_aoni + g * i_an ) / dst[3];
|
||||
dst[2] = ( dst[2] * i_aoni + b * i_an ) / dst[3];
|
||||
}
|
||||
}
|
||||
}
|
||||
dst += 4;
|
||||
}
|
||||
srcrow += i_pitch_src;
|
||||
dstrow += i_pitch_dst;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user