Example #1
0
File: b4s.c Project: cobr123/qtVlc
static int Demux( demux_t *p_demux )
{
    int i_ret = -1;

    xml_t *p_xml;
    xml_reader_t *p_xml_reader = NULL;
    char *psz_elname = NULL;
    input_item_t *p_input;
    char *psz_mrl = NULL, *psz_title = NULL, *psz_genre = NULL;
    char *psz_now = NULL, *psz_listeners = NULL, *psz_bitrate = NULL;
    input_item_node_t *p_subitems = NULL;

    input_item_t *p_current_input = GetCurrentItem(p_demux);

    p_xml = xml_Create( p_demux );
    if( !p_xml )
        goto end;

    psz_elname = stream_ReadLine( p_demux->s );
    free( psz_elname );
    psz_elname = NULL;

    p_xml_reader = xml_ReaderCreate( p_xml, p_demux->s );
    if( !p_xml_reader )
        goto end;

    /* xml */
    /* check root node */
    if( xml_ReaderRead( p_xml_reader ) != 1 )
    {
        msg_Err( p_demux, "invalid file (no root node)" );
        goto end;
    }

    if( xml_ReaderNodeType( p_xml_reader ) != XML_READER_STARTELEM ||
        ( psz_elname = xml_ReaderName( p_xml_reader ) ) == NULL ||
        strcmp( psz_elname, "WinampXML" ) )
    {
        msg_Err( p_demux, "invalid root node %i, %s",
                 xml_ReaderNodeType( p_xml_reader ), psz_elname );
        goto end;
    }
    FREENULL( psz_elname );

    /* root node should not have any attributes, and should only
     * contain the "playlist node */

    /* Skip until 1st child node */
    while( (i_ret = xml_ReaderRead( p_xml_reader )) == 1 &&
           xml_ReaderNodeType( p_xml_reader ) != XML_READER_STARTELEM );
    if( i_ret != 1 )
    {
        msg_Err( p_demux, "invalid file (no child node)" );
        goto end;
    }

    if( ( psz_elname = xml_ReaderName( p_xml_reader ) ) == NULL ||
        strcmp( psz_elname, "playlist" ) )
    {
        msg_Err( p_demux, "invalid child node %s", psz_elname );
        goto end;
    }
    FREENULL( psz_elname );

    // Read the attributes
    while( xml_ReaderNextAttr( p_xml_reader ) == VLC_SUCCESS )
    {
        char *psz_name = xml_ReaderName( p_xml_reader );
        char *psz_value = xml_ReaderValue( p_xml_reader );
        if( !psz_name || !psz_value )
        {
            free( psz_name );
            free( psz_value );
            goto end;
        }
        if( !strcmp( psz_name, "num_entries" ) )
        {
            msg_Dbg( p_demux, "playlist has %d entries", atoi(psz_value) );
        }
        else if( !strcmp( psz_name, "label" ) )
        {
            input_item_SetName( p_current_input, psz_value );
        }
        else
        {
            msg_Warn( p_demux, "stray attribute %s with value %s in element"
                      " 'playlist'", psz_name, psz_value );
        }
        free( psz_name );
        free( psz_value );
    }

    p_subitems = input_item_node_Create( p_current_input );

    while( (i_ret = xml_ReaderRead( p_xml_reader )) == 1 )
    {
        // Get the node type
        switch( xml_ReaderNodeType( p_xml_reader ) )
        {
            // Error
            case -1:
                goto end;

            case XML_READER_STARTELEM:
            {
                // Read the element name
                free( psz_elname );
                psz_elname = xml_ReaderName( p_xml_reader );
                if( !psz_elname )
                    goto end;

                // Read the attributes
                while( xml_ReaderNextAttr( p_xml_reader ) == VLC_SUCCESS )
                {
                    char *psz_name = xml_ReaderName( p_xml_reader );
                    char *psz_value = xml_ReaderValue( p_xml_reader );
                    if( !psz_name || !psz_value )
                    {
                        free( psz_name );
                        free( psz_value );
                        goto end;
                    }
                    if( !strcmp( psz_elname, "entry" ) &&
                        !strcmp( psz_name, "Playstring" ) )
                    {
                        psz_mrl = psz_value;
                    }
                    else
                    {
                        msg_Warn( p_demux, "unexpected attribute %s in element %s",
                                  psz_name, psz_elname );
                        free( psz_value );
                    }
                    free( psz_name );
                }
                break;
            }
            case XML_READER_TEXT:
            {
                char *psz_text = xml_ReaderValue( p_xml_reader );
                if( IsWhitespace( psz_text ) )
                {
                    free( psz_text );
                    break;
                }
                if( !strcmp( psz_elname, "Name" ) )
                {
                    psz_title = psz_text;
                }
                else if( !strcmp( psz_elname, "Genre" ) )
                {
                    psz_genre = psz_text;
                }
                else if( !strcmp( psz_elname, "Nowplaying" ) )
                {
                    psz_now = psz_text;
                }
                else if( !strcmp( psz_elname, "Listeners" ) )
                {
                    psz_listeners = psz_text;
                }
                else if( !strcmp( psz_elname, "Bitrate" ) )
                {
                    psz_bitrate = psz_text;
                }
                else if( !strcmp( psz_elname, "" ) )
                {
                    free( psz_text );
                }
                else
                {
                    msg_Warn( p_demux, "unexpected text in element '%s'",
                              psz_elname );
                    free( psz_text );
                }
                break;
            }
            // End element
            case XML_READER_ENDELEM:
            {
                // Read the element name
                free( psz_elname );
                psz_elname = xml_ReaderName( p_xml_reader );
                if( !psz_elname )
                    goto end;
                if( !strcmp( psz_elname, "entry" ) )
                {
                    p_input = input_item_New( p_demux, psz_mrl, psz_title );
                    if( psz_now )
                        input_item_SetNowPlaying( p_input, psz_now );
                    if( psz_genre )
                        input_item_SetGenre( p_input, psz_genre );
                    if( psz_listeners )
                        msg_Err( p_demux, "Unsupported meta listeners" );
                    if( psz_bitrate )
                        msg_Err( p_demux, "Unsupported meta bitrate" );

                    input_item_node_AppendItem( p_subitems, p_input );
                    vlc_gc_decref( p_input );
                    FREENULL( psz_title );
                    FREENULL( psz_mrl );
                    FREENULL( psz_genre );
                    FREENULL( psz_bitrate );
                    FREENULL( psz_listeners );
                    FREENULL( psz_now );
                }
                free( psz_elname );
                psz_elname = strdup( "" );

                break;
            }
        }
    }

    if( i_ret != 0 )
    {
        msg_Warn( p_demux, "error while parsing data" );
        i_ret = 0; /* Needed for correct operation of go back */
    }

end:
    free( psz_elname );

    if( p_subitems )
        input_item_node_PostAndDelete( p_subitems );

    vlc_gc_decref( p_current_input );
    if( p_xml_reader )
        xml_ReaderDelete( p_xml, p_xml_reader );
    if( p_xml )
        xml_Delete( p_xml );
    return i_ret;
}
Example #2
0
File: xspf.c Project: Kafay/vlc
/**
 * \brief demuxer function for XSPF parsing
 */
int Demux( demux_t *p_demux )
{
    int i_ret = 1;
    xml_t *p_xml = NULL;
    xml_reader_t *p_xml_reader = NULL;
    char *psz_name = NULL;
    INIT_PLAYLIST_STUFF;
    p_demux->p_sys->pp_tracklist = NULL;
    p_demux->p_sys->i_tracklist_entries = 0;
    p_demux->p_sys->i_track_id = -1;
    p_demux->p_sys->psz_base = NULL;

    /* create new xml parser from stream */
    p_xml = xml_Create( p_demux );
    if( !p_xml )
        i_ret = -1;
    else
    {
        p_xml_reader = xml_ReaderCreate( p_xml, p_demux->s );
        if( !p_xml_reader )
            i_ret = -1;
    }

    /* locating the root node */
    if( i_ret == 1 )
    {
        do
        {
            if( xml_ReaderRead( p_xml_reader ) != 1 )
            {
                msg_Err( p_demux, "can't read xml stream" );
                i_ret = -1;
            }
        } while( i_ret == VLC_SUCCESS &&
                 xml_ReaderNodeType( p_xml_reader ) != XML_READER_STARTELEM );
    }
    /* checking root node name */
    if( i_ret == 1 )
    {
        psz_name = xml_ReaderName( p_xml_reader );
        if( !psz_name || strcmp( psz_name, "playlist" ) )
        {
            msg_Err( p_demux, "invalid root node name: %s", psz_name );
            i_ret = -1;
        }
        FREE_NAME();
    }

    if( i_ret == 1 )
        i_ret = parse_playlist_node( p_demux, p_current_input,
                                     p_xml_reader, "playlist" ) ? 0 : -1;

    int i;
    for( i = 0 ; i < p_demux->p_sys->i_tracklist_entries ; i++ )
    {
        input_item_t *p_new_input = p_demux->p_sys->pp_tracklist[i];
        if( p_new_input )
        {
            input_item_AddSubItem( p_current_input, p_new_input );
        }
    }

    HANDLE_PLAY_AND_RELEASE;
    if( p_xml_reader )
        xml_ReaderDelete( p_xml, p_xml_reader );
    if( p_xml )
        xml_Delete( p_xml );
    return i_ret; /* Needed for correct operation of go back */
}
Example #3
0
/**
 * \brief demuxer function for XSPF parsing
 */
int Demux( demux_t *p_demux )
{
    int i_ret = -1;
    xml_t *p_xml = NULL;
    xml_reader_t *p_xml_reader = NULL;
    char *psz_name = NULL;
    input_item_t *p_current_input = GetCurrentItem(p_demux);
    p_demux->p_sys->pp_tracklist = NULL;
    p_demux->p_sys->i_tracklist_entries = 0;
    p_demux->p_sys->i_track_id = -1;
    p_demux->p_sys->psz_base = NULL;

    /* create new xml parser from stream */
    p_xml = xml_Create( p_demux );
    if( !p_xml )
        goto end;

    p_xml_reader = xml_ReaderCreate( p_xml, p_demux->s );
    if( !p_xml_reader )
        goto end;

    /* locating the root node */
    do
    {
        if( xml_ReaderRead( p_xml_reader ) != 1 )
        {
            msg_Err( p_demux, "can't read xml stream" );
            goto end;
        }
    } while( xml_ReaderNodeType( p_xml_reader ) != XML_READER_STARTELEM );

    /* checking root node name */
    psz_name = xml_ReaderName( p_xml_reader );
    if( !psz_name || strcmp( psz_name, "playlist" ) )
    {
        msg_Err( p_demux, "invalid root node name: %s", psz_name );
        free( psz_name );
        goto end;
    }
    free( psz_name );

    i_ret = parse_playlist_node( p_demux, p_current_input,
                                 p_xml_reader, "playlist" ) ? 0 : -1;

    for( int i = 0 ; i < p_demux->p_sys->i_tracklist_entries ; i++ )
    {
        input_item_t *p_new_input = p_demux->p_sys->pp_tracklist[i];
        if( p_new_input )
        {
            input_item_AddSubItem( p_current_input, p_new_input );
        }
    }

end:
    vlc_gc_decref(p_current_input);
    if( p_xml_reader )
        xml_ReaderDelete( p_xml, p_xml_reader );
    if( p_xml )
        xml_Delete( p_xml );
    return i_ret; /* Needed for correct operation of go back */
}
Example #4
0
/****************************************************************************
 * Parse the rss feed
 ***************************************************************************/
static bool ParseFeed( filter_t *p_filter, xml_reader_t *p_xml_reader,
                      rss_feed_t *p_feed )
{
    VLC_UNUSED(p_filter);
    char *psz_eltname = NULL;

    bool b_is_item = false;
    bool b_is_image = false;

    int i_item = 0;

    while( xml_ReaderRead( p_xml_reader ) == 1 )
    {
        switch( xml_ReaderNodeType( p_xml_reader ) )
        {
        // Error
        case -1:
            goto end;

        case XML_READER_STARTELEM:
            free( psz_eltname );
            psz_eltname = xml_ReaderName( p_xml_reader );
            if( !psz_eltname )
                goto end;

#ifdef RSS_DEBUG
            msg_Dbg( p_filter, "element name: %s", psz_eltname );
#endif
            /* rss or atom */
            if( !strcmp( psz_eltname, "item" ) || !strcmp( psz_eltname, "entry" ) )
            {
                b_is_item = true;
                p_feed->i_items++;
                p_feed->p_items = xrealloc( p_feed->p_items,
                                     p_feed->i_items * sizeof( rss_item_t ) );
                p_feed->p_items[p_feed->i_items-1].psz_title = NULL;
                p_feed->p_items[p_feed->i_items-1].psz_description = NULL;
                p_feed->p_items[p_feed->i_items-1].psz_link = NULL;
            }
            /* rss */
            else if( !strcmp( psz_eltname, "image" ) )
            {
                b_is_image = true;
            }
            /* atom */
            else if( !strcmp( psz_eltname, "link" ) )
            {
                char *psz_href = NULL;
                char *psz_rel = NULL;
                while( xml_ReaderNextAttr( p_xml_reader ) == VLC_SUCCESS )
                {
                    char *psz_name = xml_ReaderName( p_xml_reader );
                    char *psz_value = xml_ReaderValue( p_xml_reader );
                    if( !strcmp( psz_name, "rel" ) )
                    {
                        free( psz_rel );
                        psz_rel = psz_value;
                    }
                    else if( !strcmp( psz_name, "href" ) )
                    {
                        free( psz_href );
                        psz_href = psz_value;
                    }
                    else
                    {
                        free( psz_value );
                    }
                    free( psz_name );
                }

                /* "rel" and "href" must be defined */
                if( psz_rel && psz_href )
                {
                    if( !strcmp( psz_rel, "alternate" ) && !b_is_item &&
                        !b_is_image && !p_feed->psz_link )
                    {
                        p_feed->psz_link = psz_href;
                    }
                    /* this isn't in the rfc but i found some ... */
                    else if( ( !strcmp( psz_rel, "logo" ) ||
                               !strcmp( psz_rel, "icon" ) )
                             && !b_is_item && !b_is_image
                             && !p_feed->psz_image )
                    {
                        p_feed->psz_image = psz_href;
                    }
                    else
                    {
                        free( psz_href );
                    }
                }
                else
                {
                    free( psz_href );
                }
                free( psz_rel );
            }
            break;

        case XML_READER_ENDELEM:
            free( psz_eltname );
            psz_eltname = xml_ReaderName( p_xml_reader );
            if( !psz_eltname )
                goto end;

#ifdef RSS_DEBUG
            msg_Dbg( p_filter, "element end : %s", psz_eltname );
#endif
            /* rss or atom */
            if( !strcmp( psz_eltname, "item" ) || !strcmp( psz_eltname, "entry" ) )
            {
                b_is_item = false;
                i_item++;
            }
            /* rss */
            else if( !strcmp( psz_eltname, "image" ) )
            {
                b_is_image = false;
            }
            FREENULL( psz_eltname );
            break;

        case XML_READER_TEXT:
        {
            if( !psz_eltname )
                break;
            char *psz_eltvalue = xml_ReaderValue( p_xml_reader );
            if( !psz_eltvalue )
                goto end;

            char *psz_clean = removeWhiteChars( psz_eltvalue );
            free( psz_eltvalue );
            psz_eltvalue = psz_clean;

#ifdef RSS_DEBUG
            msg_Dbg( p_filter, "  text : <%s>", psz_eltvalue );
#endif
            /* Is it an item ? */
            if( b_is_item )
            {
                rss_item_t *p_item = p_feed->p_items+i_item;
                /* rss/atom */
                if( !strcmp( psz_eltname, "title" ) && !p_item->psz_title )
                {
                    p_item->psz_title = psz_eltvalue;
                }
                else if( !strcmp( psz_eltname, "link" ) /* rss */
                         && !p_item->psz_link )
                {
                    p_item->psz_link = psz_eltvalue;
                }
                /* rss/atom */
                else if( ( !strcmp( psz_eltname, "description" ) ||
                           !strcmp( psz_eltname, "summary" ) )
                          && !p_item->psz_description )
                {
                    p_item->psz_description = psz_eltvalue;
                }
                else
                {
                    free( psz_eltvalue );
                }
            }
            /* Is it an image ? */
            else if( b_is_image )
            {
                if( !strcmp( psz_eltname, "url" ) && !p_feed->psz_image )
                    p_feed->psz_image = psz_eltvalue;
                else
                    free( psz_eltvalue );
            }
            else
            {
                /* rss/atom */
                if( !strcmp( psz_eltname, "title" ) && !p_feed->psz_title )
                {
                    p_feed->psz_title = psz_eltvalue;
                }
                /* rss */
                else if( !strcmp( psz_eltname, "link" ) && !p_feed->psz_link )
                {
                    p_feed->psz_link = psz_eltvalue;
                }
                /* rss ad atom */
                else if( ( !strcmp( psz_eltname, "description" ) ||
                           !strcmp( psz_eltname, "subtitle" ) )
                         && !p_feed->psz_description )
                {
                    p_feed->psz_description = psz_eltvalue;
                }
                /* rss */
                else if( ( !strcmp( psz_eltname, "logo" ) ||
                           !strcmp( psz_eltname, "icon" ) )
                         && !p_feed->psz_image )
                {
                    p_feed->psz_image = psz_eltvalue;
                }
                else
                {
                    free( psz_eltvalue );
                }
            }
            break;
        }
        }
    }

    free( psz_eltname );
    return true;

end:
    free( psz_eltname );
    return false;
}
Example #5
0
static void ParseUSFHeaderTags( decoder_t *p_dec, xml_reader_t *p_xml_reader )
{
    decoder_sys_t *p_sys = p_dec->p_sys;
    char *psz_node;
    ssa_style_t *p_ssa_style = NULL;
    int i_style_level = 0;
    int i_metadata_level = 0;

    while ( xml_ReaderRead( p_xml_reader ) == 1 )
    {
        switch ( xml_ReaderNodeType( p_xml_reader ) )
        {
            case XML_READER_TEXT:
            case XML_READER_NONE:
                break;
            case XML_READER_ENDELEM:
                psz_node = xml_ReaderName( p_xml_reader );

                if( !psz_node )
                    break;
                switch (i_style_level)
                {
                    case 0:
                        if( !strcasecmp( "metadata", psz_node ) && (i_metadata_level == 1) )
                        {
                            i_metadata_level--;
                        }
                        break;
                    case 1:
                        if( !strcasecmp( "styles", psz_node ) )
                        {
                            i_style_level--;
                        }
                        break;
                    case 2:
                        if( !strcasecmp( "style", psz_node ) )
                        {
                            TAB_APPEND( p_sys->i_ssa_styles, p_sys->pp_ssa_styles, p_ssa_style );

                            p_ssa_style = NULL;
                            i_style_level--;
                        }
                        break;
                }

                free( psz_node );
                break;
            case XML_READER_STARTELEM:
                psz_node = xml_ReaderName( p_xml_reader );

                if( !psz_node )
                    break;

                if( !strcasecmp( "metadata", psz_node ) && (i_style_level == 0) )
                {
                    i_metadata_level++;
                }
                else if( !strcasecmp( "resolution", psz_node ) &&
                         ( i_metadata_level == 1) )
                {
                    while ( xml_ReaderNextAttr( p_xml_reader ) == VLC_SUCCESS )
                    {
                        char *psz_name = xml_ReaderName ( p_xml_reader );
                        char *psz_value = xml_ReaderValue ( p_xml_reader );

                        if( psz_name && psz_value )
                        {
                            if( !strcasecmp( "x", psz_name ) )
                                p_sys->i_original_width = atoi( psz_value );
                            else if( !strcasecmp( "y", psz_name ) )
                                p_sys->i_original_height = atoi( psz_value );
                        }
                        free( psz_name );
                        free( psz_value );
                    }
                }
                else if( !strcasecmp( "styles", psz_node ) && (i_style_level == 0) )
                {
                    i_style_level++;
                }
                else if( !strcasecmp( "style", psz_node ) && (i_style_level == 1) )
                {
                    i_style_level++;

                    p_ssa_style = calloc( 1, sizeof(ssa_style_t) );
                    if( !p_ssa_style )
                    {
                        free( psz_node );
                        return;
                    }
                    /* All styles are supposed to default to Default, and then
                     * one or more settings are over-ridden.
                     * At the moment this only effects styles defined AFTER
                     * Default in the XML
                     */
                    int i;
                    for( i = 0; i < p_sys->i_ssa_styles; i++ )
                    {
                        if( !strcasecmp( p_sys->pp_ssa_styles[i]->psz_stylename, "Default" ) )
                        {
                            ssa_style_t *p_default_style = p_sys->pp_ssa_styles[i];

                            memcpy( p_ssa_style, p_default_style, sizeof( ssa_style_t ) );
                            //FIXME: Make font_style a pointer. Actually we double copy some data here,
                            //   we use text_style_Copy to avoid copying psz_fontname, though .
                            text_style_Copy( &p_ssa_style->font_style, &p_default_style->font_style );
                            p_ssa_style->psz_stylename = NULL;
                        }
                    }

                    while ( xml_ReaderNextAttr( p_xml_reader ) == VLC_SUCCESS )
                    {
                        char *psz_name = xml_ReaderName ( p_xml_reader );
                        char *psz_value = xml_ReaderValue ( p_xml_reader );

                        if( psz_name && psz_value )
                        {
                            if( !strcasecmp( "name", psz_name ) )
                                p_ssa_style->psz_stylename = strdup( psz_value );
                        }
                        free( psz_name );
                        free( psz_value );
                    }
                }
                else if( !strcasecmp( "fontstyle", psz_node ) && (i_style_level == 2) )
                {
                    while ( xml_ReaderNextAttr( p_xml_reader ) == VLC_SUCCESS )
                    {
                        char *psz_name = xml_ReaderName ( p_xml_reader );
                        char *psz_value = xml_ReaderValue ( p_xml_reader );

                        if( psz_name && psz_value )
                        {
                            if( !strcasecmp( "face", psz_name ) )
                            {
                                free( p_ssa_style->font_style.psz_fontname );
                                p_ssa_style->font_style.psz_fontname = strdup( psz_value );
                            }
                            else if( !strcasecmp( "size", psz_name ) )
                            {
                                if( ( *psz_value == '+' ) || ( *psz_value == '-' ) )
                                {
                                    int i_value = atoi( psz_value );

                                    if( ( i_value >= -5 ) && ( i_value <= 5 ) )
                                        p_ssa_style->font_style.i_font_size  +=
                                            ( i_value * p_ssa_style->font_style.i_font_size ) / 10;
                                    else if( i_value < -5 )
                                        p_ssa_style->font_style.i_font_size  = - i_value;
                                    else if( i_value > 5 )
                                        p_ssa_style->font_style.i_font_size  = i_value;
                                }
                                else
                                    p_ssa_style->font_style.i_font_size  = atoi( psz_value );
                            }
                            else if( !strcasecmp( "italic", psz_name ) )
                            {
                                if( !strcasecmp( "yes", psz_value ))
                                    p_ssa_style->font_style.i_style_flags |= STYLE_ITALIC;
                                else
                                    p_ssa_style->font_style.i_style_flags &= ~STYLE_ITALIC;
                            }
                            else if( !strcasecmp( "weight", psz_name ) )
                            {
                                if( !strcasecmp( "bold", psz_value ))
                                    p_ssa_style->font_style.i_style_flags |= STYLE_BOLD;
                                else
                                    p_ssa_style->font_style.i_style_flags &= ~STYLE_BOLD;
                            }
                            else if( !strcasecmp( "underline", psz_name ) )
                            {
                                if( !strcasecmp( "yes", psz_value ))
                                    p_ssa_style->font_style.i_style_flags |= STYLE_UNDERLINE;
                                else
                                    p_ssa_style->font_style.i_style_flags &= ~STYLE_UNDERLINE;
                            }
                            else if( !strcasecmp( "color", psz_name ) )
                            {
                                if( *psz_value == '#' )
                                {
                                    unsigned long col = strtol(psz_value+1, NULL, 16);
                                    p_ssa_style->font_style.i_font_color = (col & 0x00ffffff);
                                    p_ssa_style->font_style.i_font_alpha = (col >> 24) & 0xff;
                                }
                            }
                            else if( !strcasecmp( "outline-color", psz_name ) )
                            {
                                if( *psz_value == '#' )
                                {
                                    unsigned long col = strtol(psz_value+1, NULL, 16);
                                    p_ssa_style->font_style.i_outline_color = (col & 0x00ffffff);
                                    p_ssa_style->font_style.i_outline_alpha = (col >> 24) & 0xff;
                                }
                            }
                            else if( !strcasecmp( "outline-level", psz_name ) )
                            {
                                p_ssa_style->font_style.i_outline_width = atoi( psz_value );
                            }
                            else if( !strcasecmp( "shadow-color", psz_name ) )
                            {
                                if( *psz_value == '#' )
                                {
                                    unsigned long col = strtol(psz_value+1, NULL, 16);
                                    p_ssa_style->font_style.i_shadow_color = (col & 0x00ffffff);
                                    p_ssa_style->font_style.i_shadow_alpha = (col >> 24) & 0xff;
                                }
                            }
                            else if( !strcasecmp( "shadow-level", psz_name ) )