⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 svg.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 2 页
字号:
    int channels_in;    int alpha;    picture_t *p_pic;    subpicture_region_t *p_region_tmp;    if ( p_filter->p_sys->i_width != i_width ||         p_filter->p_sys->i_height != i_height )    {        svg_set_size( p_filter, i_width, i_height );        p_svg->p_rendition = NULL;    }    if( p_svg->p_rendition == NULL ) {        svg_RenderPicture( p_filter, p_svg );        if( ! p_svg->p_rendition )        {            msg_Err( p_filter, "Cannot render SVG" );            return VLC_EGENERIC;        }    }    i_width = gdk_pixbuf_get_width( p_svg->p_rendition );    i_height = gdk_pixbuf_get_height( p_svg->p_rendition );    /* Create a new subpicture region */    memset( &fmt, 0, sizeof( video_format_t ) );    fmt.i_chroma = VLC_FOURCC( 'Y','U','V','A' );    fmt.i_aspect = VOUT_ASPECT_FACTOR;    fmt.i_width = fmt.i_visible_width = i_width;    fmt.i_height = fmt.i_visible_height = i_height;    fmt.i_x_offset = fmt.i_y_offset = 0;    p_region_tmp = spu_CreateRegion( p_filter, &fmt );    if( !p_region_tmp )    {        msg_Err( p_filter, "cannot allocate SPU region" );        return VLC_EGENERIC;    }    p_region->fmt = p_region_tmp->fmt;    p_region->picture = p_region_tmp->picture;    free( p_region_tmp );    p_region->i_x = p_region->i_y = 0;    p_y = p_region->picture.Y_PIXELS;    p_u = p_region->picture.U_PIXELS;    p_v = p_region->picture.V_PIXELS;    p_a = p_region->picture.A_PIXELS;    i_pitch = p_region->picture.Y_PITCH;    i_u_pitch = p_region->picture.U_PITCH;    /* Initialize the region pixels (only the alpha will be changed later) */    memset( p_y, 0x00, i_pitch * p_region->fmt.i_height );    memset( p_u, 0x80, i_u_pitch * p_region->fmt.i_height );    memset( p_v, 0x80, i_u_pitch * p_region->fmt.i_height );    p_pic = &p_region->picture;    /* Copy the data */    /* This rendering code is in no way optimized. If someone has some time to       make it work faster or better, please do.    */    /*      p_pixbuf->get_rowstride() is the number of bytes in a line.      p_pixbuf->get_height() is the number of lines.      The number of bytes of p_pixbuf->p_pixels is get_rowstride * get_height      if( has_alpha() ) {      alpha = pixels [ n_channels * ( y*rowstride + x ) + 3 ];      }      red   = pixels [ n_channels * ( y*rowstride ) + x ) ];      green = pixels [ n_channels * ( y*rowstride ) + x ) + 1 ];      blue  = pixels [ n_channels * ( y*rowstride ) + x ) + 2 ];    */    pixels_in = gdk_pixbuf_get_pixels( p_svg->p_rendition );    rowstride_in = gdk_pixbuf_get_rowstride( p_svg->p_rendition );    channels_in = gdk_pixbuf_get_n_channels( p_svg->p_rendition );    alpha = gdk_pixbuf_get_has_alpha( p_svg->p_rendition );    /*      This crashes the plugin (if !alpha). As there is always an alpha value,      it does not matter for the moment :    if( !alpha )      memset( p_a, 0xFF, i_pitch * p_region->fmt.i_height );    */#define INDEX_IN( x, y ) ( y * rowstride_in + x * channels_in )#define INDEX_OUT( x, y ) ( y * i_pitch + x * p_pic->p[Y_PLANE].i_pixel_pitch )    for( y = 0; y < i_height; y++ )    {        for( x = 0; x < i_width; x++ )        {            guchar *p_in;            int i_out;            p_in = &pixels_in[INDEX_IN( x, y )];#define R( pixel ) *pixel#define G( pixel ) *( pixel+1 )#define B( pixel ) *( pixel+2 )#define ALPHA( pixel ) *( pixel+3 )            /* From http://www.geocrawler.com/archives/3/8263/2001/6/0/6020594/ :               Y = 0.29900 * R + 0.58700 * G + 0.11400 * B               U = -0.1687 * r  - 0.3313 * g + 0.5 * b + 128               V = 0.5   * r - 0.4187 * g - 0.0813 * b + 128            */            if ( alpha ) {                i_out = INDEX_OUT( x, y );                p_pic->Y_PIXELS[i_out] = .299 * R( p_in ) + .587 * G( p_in ) + .114 * B( p_in );                p_pic->U_PIXELS[i_out] = -.1687 * R( p_in ) - .3313 * G( p_in ) + .5 * B( p_in ) + 128;                p_pic->V_PIXELS[i_out] = .5 * R( p_in ) - .4187 * G( p_in ) - .0813 * B( p_in ) + 128;                p_pic->A_PIXELS[i_out] = ALPHA( p_in );            }        }    }    return VLC_SUCCESS;}static void svg_set_size( filter_t *p_filter, int width, int height ){  p_filter->p_sys->i_width = width;  p_filter->p_sys->i_height = height;}static void svg_SizeCallback( int *width, int *height, gpointer data ){    filter_t *p_filter = data;    *width = p_filter->p_sys->i_width;    *height = p_filter->p_sys->i_height;    return;}static void svg_RenderPicture( filter_t *p_filter,                               svg_rendition_t *p_svg ){    /* Render the SVG string p_string->psz_text into a new picture_t       p_string->p_rendition with dimensions ( ->i_width, ->i_height ) */    RsvgHandle *p_handle;    GError *error = NULL;    p_svg->p_rendition = NULL;    p_handle = rsvg_handle_new();    if( !p_handle )    {        msg_Err( p_filter, "Error creating SVG reader: %s", error->message );        return;    }    rsvg_handle_set_size_callback( p_handle, svg_SizeCallback, p_filter, NULL );    if( ! rsvg_handle_write( p_handle,                 ( guchar* )p_svg->psz_text, strlen( p_svg->psz_text ),                 &error ) )    {        msg_Err( p_filter, "error while rendering SVG: %s\n", error->message );        g_object_unref( G_OBJECT( p_handle ) );        return;    }    if( ! rsvg_handle_close( p_handle, &error ) )    {        msg_Err( p_filter, "error while rendering SVG (close): %s\n", error->message );        g_object_unref( G_OBJECT( p_handle ) );        return;    }    p_svg->p_rendition = rsvg_handle_get_pixbuf( p_handle );    g_object_unref( G_OBJECT( p_handle ) );}static int RenderText( filter_t *p_filter, subpicture_region_t *p_region_out,                       subpicture_region_t *p_region_in ){    filter_sys_t *p_sys = p_filter->p_sys;    svg_rendition_t *p_svg = NULL;    char *psz_string;    /* Sanity check */    if( !p_region_in || !p_region_out ) return VLC_EGENERIC;    psz_string = p_region_in->psz_text;    if( !psz_string || !*psz_string ) return VLC_EGENERIC;    p_svg = ( svg_rendition_t * )malloc( sizeof( svg_rendition_t ) );    if( !p_svg )        return VLC_ENOMEM;    p_region_out->i_x = p_region_in->i_x;    p_region_out->i_y = p_region_in->i_y;    /* Check if the data is SVG or pure text. In the latter case,       convert the text to SVG. FIXME: find a better test */    if( strstr( psz_string, "<svg" ))    {        /* Data is SVG: duplicate */        p_svg->psz_text = strdup( psz_string );        if( !p_svg->psz_text )        {            free( p_svg );            return VLC_ENOMEM;        }    }    else    {        /* Data is text. Convert to SVG */        /* FIXME: handle p_style attributes */        int length;        char* psz_template = p_sys->psz_template;        length = strlen( psz_string ) + strlen( psz_template ) + 42;        p_svg->psz_text = malloc( ( length + 1 ) * sizeof( char ) );        if( !p_svg->psz_text )        {            free( p_svg );            return VLC_ENOMEM;        }        memset( p_svg->psz_text, 0, length + 1 );        snprintf( p_svg->psz_text, length, psz_template, psz_string );    }    p_svg->i_width = p_sys->i_width;    p_svg->i_height = p_sys->i_height;    p_svg->i_chroma = VLC_FOURCC( 'Y','U','V','A' );    /* Render the SVG.       The input data is stored in the p_string structure,       and the function updates the p_rendition attribute. */    svg_RenderPicture( p_filter, p_svg );    Render( p_filter, p_region_out, p_svg, p_svg->i_width, p_svg->i_height );    FreeString( p_svg );    return VLC_SUCCESS;}static void FreeString( svg_rendition_t *p_svg ){    free( p_svg->psz_text );    /* p_svg->p_rendition is a GdkPixbuf, and its allocation is       managed through ref. counting */    if( p_svg->p_rendition )        g_object_unref( p_svg->p_rendition );    free( p_svg );}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -