/*****************************************************************************
* subtitles.c
*****************************************************************************
- * Copyright (C) 2003-2004 VideoLAN
+ * Copyright (C) 2003-2004 VideoLAN (Centrale Réseaux) and its contributors
* $Id$
*
* Authors: Derk-Jan Hartman <hartman at videolan.org>
#include <vlc/vlc.h>
#include <vlc/input.h>
-#include "ninput.h"
-
#ifdef HAVE_DIRENT_H
# include <dirent.h>
-#else
-# include "../extras/dirent.h"
#endif
#include <ctype.h>
/**
* The possible extentions for subtitle files we support
*/
-static const char * sub_exts[] = { "utf", "utf8", "utf-8", "sub", "srt", "smi", "txt", "ssa", NULL};
+static const char * sub_exts[] = { "utf", "utf8", "utf-8", "sub", "srt", "smi", "txt", "ssa", "idx", NULL};
/* extensions from unsupported types */
/* rt, aqt, jss, js, ass */
{
int priority;
char *psz_fname;
+ char *psz_ext;
} subfn;
static int compare_sub_priority( const void *a, const void *b )
return 1;
}
+#ifndef UNDER_CE
return strcoll(((subfn*)a)->psz_fname, ((subfn*)b)->psz_fname);
+#else
+ return strcmp(((subfn*)a)->psz_fname, ((subfn*)b)->psz_fname);
+#endif
}
/**
- * Detect subtitle files.
- *
- * When called this function will split up the psz_fname string into a
- * directory, filename and extension. It then opens the directory
- * in which the file resides and tries to find possible matches of
- * subtitles files.
- *
- * \ingroup Demux
- * \param p_this the calling \ref input_thread_t
- * \param psz_path a list of subdirectories (separated by a ',') to look in.
- * \param psz_fname the complete filename to base the search on.
- * \return a NULL terminated array of filenames with detected possible subtitles.
- * The array contains max MAX_SUBTITLE_FILES items and you need to free it after use.
+ * Convert a list of paths separated by ',' to a char**
*/
-char **subtitles_Detect( input_thread_t *p_this, char *psz_path,
- char *psz_fname )
+static char **paths_to_list( char *psz_dir, char *psz_path )
{
- /* variables to be used for derivatives of psz_fname */
- char *f_dir, *f_fname, *f_fname_noext, *f_fname_trim, *tmp;
- /* variables to be used for derivatives FILE *f */
- char *tmp_fname_noext, *tmp_fname_trim, *tmp_fname_ext, *tmpresult;
-
- vlc_value_t fuzzy;
- int len, i, j, i_sub_count, i_nb_subdirs;
- unsigned int k, i_max_sub_len;
- subfn *result; /* unsorted results */
- char **result2; /* sorted results */
+ unsigned int i, k, i_nb_subdirs;
char **subdirs; /* list of subdirectories to look in */
-
- FILE *f;
- DIR *d;
- struct dirent *de;
-
+
i_nb_subdirs = 1;
for( k = 0; k < strlen( psz_path ); k++ )
{
- if( psz_path[k] == ',' )
+ if( psz_path[k] == ',' )
{
i_nb_subdirs++;
}
}
-
- i_max_sub_len = 0;
- if( i_nb_subdirs >= 0 )
+
+ if( i_nb_subdirs > 0 )
{
- char *psz_parser;
-
- subdirs = (char**)malloc( sizeof(char*) * i_nb_subdirs );
+ char *psz_parser, *psz_temp;
+
+ subdirs = (char**)malloc( sizeof(char*) * ( i_nb_subdirs + 1 ) );
+ memset( subdirs, 0, sizeof(char*) * ( i_nb_subdirs + 1 ) );
i = 0;
psz_parser = psz_path;
while( psz_parser && *psz_parser )
psz_parser++;
}
}
- subdirs[i] = strdup( psz_subdir );
- i++;
- if( strlen( psz_subdir ) > i_max_sub_len )
+ if( strlen( psz_subdir ) > 0 )
{
- i_max_sub_len = strlen( psz_subdir );
+ psz_temp = (char *)malloc( strlen(psz_dir)
+ + strlen(psz_subdir) + 2 );
+ if( psz_temp )
+ {
+ sprintf( psz_temp, "%s%s%c",
+ psz_subdir[0] == '.' ? psz_dir : "",
+ psz_subdir,
+ psz_subdir[strlen(psz_subdir) - 1] ==
+ DIRECTORY_SEPARATOR ? '\0' : DIRECTORY_SEPARATOR );
+ subdirs[i] = psz_temp;
+ i++;
+ }
}
}
- }
- else
+ subdirs[i] = NULL;
+ }
+ else
{
- i_nb_subdirs = -1;
subdirs = NULL;
}
+ return subdirs;
+}
+
+/**
+ * Detect subtitle files.
+ *
+ * When called this function will split up the psz_fname string into a
+ * directory, filename and extension. It then opens the directory
+ * in which the file resides and tries to find possible matches of
+ * subtitles files.
+ *
+ * \ingroup Demux
+ * \param p_this the calling \ref input_thread_t
+ * \param psz_path a list of subdirectories (separated by a ',') to look in.
+ * \param psz_fname the complete filename to base the search on.
+ * \return a NULL terminated array of filenames with detected possible subtitles.
+ * The array contains max MAX_SUBTITLE_FILES items and you need to free it after use.
+ */
+char **subtitles_Detect( input_thread_t *p_this, char *psz_path,
+ char *psz_fname )
+{
+ /* variables to be used for derivatives of psz_fname */
+ char *f_dir, *f_fname, *f_fname_noext, *f_fname_trim, *tmp;
+ /* variables to be used for derivatives FILE *f */
+ char *tmp_fname_noext, *tmp_fname_trim, *tmp_fname_ext, *tmpresult;
+ vlc_value_t fuzzy;
+ int len, i, j, i_sub_count, i_result2;
+ subfn *result; /* unsorted results */
+ char **result2; /* sorted results */
+ char **tmp_subdirs, **subdirs; /* list of subdirectories to look in */
+
+ FILE *f;
+ DIR *d;
+ struct dirent *de;
+
+ if( !strncmp( psz_fname, "file://", 7 ) )
+ {
+ psz_fname += 7;
+ }
i_sub_count = 0;
- len = ( strlen( psz_fname ) > 256 ? strlen( psz_fname ) : 256 ) +
- ( i_max_sub_len > 256 ? i_max_sub_len : 256 ) + 2;
+ len = strlen( psz_fname ) > 256 ? strlen( psz_fname ) : 256;
f_dir = (char*)malloc(len);
f_fname = (char*)malloc(len);
strcpy_trim( f_fname_trim, f_fname_noext );
var_Get( p_this, "sub-autodetect-fuzzy", &fuzzy );
+ tmp_subdirs = paths_to_list( f_dir, psz_path );
+ subdirs = tmp_subdirs;
- for( j = -1; j < i_nb_subdirs; j++)
+ for( j = -1; j == -1 || ( j >= 0 && subdirs != NULL && *subdirs != NULL );
+ j++)
{
- if( j >= 0 )
- {
- if( subdirs[j] && subdirs[j][0] == '.' )
- {
- char* psz_dir;
- psz_dir = (char *)malloc( len );
- if( psz_dir )
- {
- sprintf( psz_dir, "%s%s", f_dir, subdirs[j] );
- d = opendir( psz_dir );
- free( psz_dir );
- }
- else d = NULL;
- }
- else
- {
- d = opendir( subdirs[j] );
- }
- }
- else
- {
- d = opendir( f_dir );
- }
-
+ d = opendir( j < 0 ? f_dir : *subdirs );
if( d )
{
int b_found;
msg_Dbg( p_this, "looking for a subtitle file in %s",
- j < 0 ? f_dir : subdirs[j] );
+ j < 0 ? f_dir : *subdirs );
while( ( de = readdir( d ) ) )
{
/* retrieve various parts of the filename */
if( i_prio >= fuzzy.i_int )
{
- sprintf( tmpresult, "%s%s", j == 0 ? f_dir : psz_path,
+ sprintf( tmpresult, "%s%s", j == -1 ? f_dir : *subdirs,
de->d_name );
msg_Dbg( p_this, "autodetected subtitle: %s with "
"priority %d", de->d_name, i_prio );
fclose( f );
result[i_sub_count].priority = i_prio;
result[i_sub_count].psz_fname = strdup(tmpresult);
+ result[i_sub_count].psz_ext = strdup(tmp_fname_ext);
i_sub_count++;
}
}
}
closedir( d );
}
+ if( j >= 0 ) free( *subdirs++ );
}
+ if( tmp_subdirs ) free( tmp_subdirs );
+
free( f_dir );
free( f_fname );
free( f_fname_noext );
result2 = (char**)malloc( sizeof(char*) * ( i_sub_count + 1 ) );
memset( result2, 0, sizeof(char*) * ( i_sub_count + 1 ) );
+ i_result2 = 0;
for( i = 0; i < i_sub_count; i++ )
{
- result2[i] = result[i].psz_fname;
+ if( result[i].psz_ext && !strcasecmp( result[i].psz_ext, "sub" ) )
+ {
+ int j;
+ for( j = 0; j < i_sub_count; j++ )
+ {
+ if( result[j].psz_fname && result[i].psz_fname &&
+ !strncasecmp( result[i].psz_fname, result[j].psz_fname, sizeof( result[i].psz_fname) - 4 ) &&
+ !strcasecmp( result[j].psz_ext, "idx" ) )
+ break;
+
+ }
+ if( j >= i_sub_count )
+ {
+ result2[i_result2] = result[i].psz_fname;
+ i_result2++;
+ }
+ }
+ else
+ {
+ result2[i_result2] = result[i].psz_fname;
+ i_result2++;
+ }
}
- result2[i_sub_count] = NULL;
free( result );
return result2;
}