1
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:
Francois Cartegnie 2021-06-29 16:01:33 +02:00 committed by Jean-Baptiste Kempf
parent ffb4a94e2b
commit 296e18b19c

View File

@ -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;
}
}