+static const char *const ppsz_filter_options[] = {
+ "file", "x", "y", "delay", "repeat", "transparency", "position", NULL
+};
+
+/*****************************************************************************
+ * Structure to hold the set of individual logo image names, times,
+ * transparencies
+ ****************************************************************************/
+typedef struct
+{
+ char *psz_file; /* candidate for deletion -- not needed */
+ int i_delay; /* -1 means use default delay */
+ int i_alpha; /* -1 means use default alpha */
+ picture_t *p_pic;
+
+} logo_t;
+
+/*****************************************************************************
+ * Logo list structure. Common to both the vout and sub picture filter
+ ****************************************************************************/
+typedef struct
+{
+ logo_t *p_logo; /* the parsing's result */
+ unsigned int i_count; /* the number of logo images to be displayed */
+
+ int i_repeat; /* how often to repeat the images, image time in ms */
+ mtime_t i_next_pic; /* when to bring up a new logo image */
+
+ unsigned int i_counter; /* index into the list of logo images */
+
+ int i_delay; /* default delay (0 - 60000 ms) */
+ int i_alpha; /* default alpha */
+
+ char *psz_filename; /* --logo-file string ( is it really useful
+ * to store it ? ) */
+
+ vlc_mutex_t lock;
+} logo_list_t;
+
+/*****************************************************************************
+ * LoadImage: loads the logo image into memory
+ *****************************************************************************/
+static picture_t *LoadImage( vlc_object_t *p_this, char *psz_filename )
+{
+ picture_t *p_pic;
+ image_handler_t *p_image;
+ video_format_t fmt_in;
+ video_format_t fmt_out;
+
+ memset( &fmt_in, 0, sizeof(video_format_t) );
+ memset( &fmt_out, 0, sizeof(video_format_t) );
+
+ fmt_out.i_chroma = VLC_FOURCC('Y','U','V','A');
+ p_image = image_HandlerCreate( p_this );
+ p_pic = image_ReadUrl( p_image, psz_filename, &fmt_in, &fmt_out );
+ image_HandlerDelete( p_image );
+
+ return p_pic;
+}
+
+/*****************************************************************************
+ * LoadLogoList: loads the logo images into memory
+ *****************************************************************************
+ * Read the logo-file input switch, obtaining a list of images and associated
+ * durations and transparencies. Store the image(s), and times. An image
+ * without a stated time or transparency will use the logo-delay and
+ * logo-transparency values.
+ *****************************************************************************/
+#define LoadLogoList( a, b ) __LoadLogoList( VLC_OBJECT( a ), b )
+static void __LoadLogoList( vlc_object_t *p_this, logo_list_t *p_logo_list )
+{
+ char *psz_list; /* the list: <logo>[,[<delay>[,[<alpha>]]]][;...] */
+ unsigned int i;
+ logo_t *p_logo; /* the parsing's result */
+
+ p_logo_list->i_counter = 0;
+ p_logo_list->i_next_pic = 0;
+
+ psz_list = strdup( p_logo_list->psz_filename );
+
+ /* Count the number logos == number of ';' + 1 */
+ p_logo_list->i_count = 1;
+ for( i = 0; i < strlen( psz_list ); i++ )
+ {
+ if( psz_list[i] == ';' ) p_logo_list->i_count++;
+ }
+
+ p_logo_list->p_logo = p_logo =
+ (logo_t *)malloc( p_logo_list->i_count * sizeof(logo_t) );
+
+ /* Fill the data */
+ for( i = 0; i < p_logo_list->i_count; i++ )
+ {
+ char *p_c;
+ char *p_c2;
+ p_c = strchr( psz_list, ';' );
+ p_c2 = strchr( psz_list, ',' );
+
+ p_logo[i].i_alpha = -1; /* use default settings */
+ p_logo[i].i_delay = -1; /* use default settings */
+
+ if( p_c2 && ( p_c2 < p_c || !p_c ) )
+ {
+ /* <logo>,<delay>[,<alpha>] type */
+ if( p_c2[1] != ',' && p_c2[1] != ';' && p_c2[1] != '\0' )
+ p_logo[i].i_delay = atoi( p_c2+1 );
+ *p_c2 = '\0';
+ if( ( p_c2 = strchr( p_c2+1, ',' ) )
+ && ( p_c2 < p_c || !p_c ) && p_c2[1] != ';' && p_c2[1] != '\0' )
+ p_logo[i].i_alpha = atoi( p_c2 + 1 );
+ }
+ else
+ {
+ /* <logo> type */
+ if( p_c ) *p_c = '\0';
+ }
+
+ p_logo[i].psz_file = strdup( psz_list );
+ p_logo[i].p_pic = LoadImage( p_this, p_logo[i].psz_file );
+
+ if( !p_logo[i].p_pic )
+ {
+ msg_Warn( p_this, "error while loading logo %s, will be skipped",
+ p_logo[i].psz_file );
+ }
+
+ if( p_c ) psz_list = p_c + 1;
+ }
+
+ for( i = 0; i < p_logo_list->i_count; i++ )
+ {
+ msg_Dbg( p_this, "logo file name %s, delay %d, alpha %d",
+ p_logo[i].psz_file, p_logo[i].i_delay, p_logo[i].i_alpha );
+ }
+
+ /* initialize so that on the first update it will wrap back to 0 */
+ p_logo_list->i_counter = p_logo_list->i_count;
+}
+
+/*****************************************************************************
+ * FreeLogoList
+ *****************************************************************************/
+static void FreeLogoList( logo_list_t *p_logo_list )
+{
+ unsigned int i;
+ FREENULL( p_logo_list->psz_filename );
+ for( i = 0; i < p_logo_list->i_count; i++ )
+ {
+ logo_t *p_logo = &p_logo_list->p_logo[i];
+ FREENULL( p_logo->psz_file );
+ if( p_logo->p_pic )
+ {
+ p_logo->p_pic->pf_release( p_logo->p_pic );
+ p_logo->p_pic = NULL;
+ }
+ }
+}
+