summaryrefslogtreecommitdiffstats
path: root/sub
diff options
context:
space:
mode:
authorUoti Urpala <uau@mplayer2.org>2012-11-22 01:22:25 +0200
committerwm4 <wm4@nowhere>2012-12-03 21:08:52 +0100
commita75e65db5defc59a8fca0024bf6559b8b6c0f1ea (patch)
tree4c697b47720c715f7ac052b2b45c04bc94a580d8 /sub
parent72205635abe7f240118658d934b5db871a184201 (diff)
downloadmpv-a75e65db5defc59a8fca0024bf6559b8b6c0f1ea.tar.bz2
mpv-a75e65db5defc59a8fca0024bf6559b8b6c0f1ea.tar.xz
subreader: fix some of ASS parser issues
The subreader.c ASS parser (used when playing an external ASS subtitle file with --no-ass for "plaintext" display) hardcodes dialogue line syntax instead of correctly reading it from the "Format: " line in the file, but tried to support a varying amount of fields by guessing where the text field (which should be last) begins. This guessing code was buggy in many ways. Remove it and hardcode skipping 9 commas before the text field, which should work for most files. I don't consider the --no-ass case important enough to implement correct parsing now. Also fix the code removing formatting tags, which failed to remove the second in a pair of two consecutive tags. Conflicts: sub/subreader.c Merged from mplayer2 commit 91f516. Essentially reverts d5b964.
Diffstat (limited to 'sub')
-rw-r--r--sub/subreader.c67
1 files changed, 22 insertions, 45 deletions
diff --git a/sub/subreader.c b/sub/subreader.c
index c7b69d711c..2bfb635d40 100644
--- a/sub/subreader.c
+++ b/sub/subreader.c
@@ -625,19 +625,14 @@ static subtitle *sub_read_line_rt(stream_t *st,subtitle *current,
static subtitle *sub_read_line_ssa(stream_t *st,subtitle *current,
struct readline_args *args)
{
-/*
- * Sub Station Alpha v4 (and v2?) scripts have 9 commas before subtitle
- * other Sub Station Alpha scripts have only 8 commas before subtitle
- * Reading the "ScriptType:" field is not reliable since many scripts appear
- * w/o it
- *
- * http://www.scriptclub.org is a good place to find more examples
- * http://www.eswat.demon.co.uk is where the SSA specs can be found
- */
+ /* Instead of hardcoding the expected fields and their order on
+ * each dialogue line, this code should parse the "Format: " line
+ * which lists the fields used in the script. As is, this may not
+ * work correctly with all scripts.
+ */
+
int utf16 = args->utf16;
int comma;
- static int max_comma = 32; /* let's use 32 for the case that the */
- /* amount of commas increase with newer SSA versions */
int hour1, min1, sec1, hunsec1,
hour2, min2, sec2, hunsec2, nothing;
@@ -647,7 +642,6 @@ static subtitle *sub_read_line_ssa(stream_t *st,subtitle *current,
line3[LINE_LEN+1],
*line2;
char *tmp;
- const char *brace;
do {
if (!stream_read_line (st, line, LINE_LEN, utf16)) return NULL;
@@ -665,21 +659,11 @@ static subtitle *sub_read_line_ssa(stream_t *st,subtitle *current,
line2=strchr(line3, ',');
if (!line2) return NULL;
- brace = strchr(line2, '{');
-
- for (comma = 4; comma < max_comma; comma ++)
- {
- tmp = line2;
- if(!(tmp=strchr(++tmp, ','))) break;
- if(brace && brace < tmp) break; // comma inside command
- if(tmp[1] == ' ') break;
- /* a space after a comma means we're already in a sentence */
- line2 = tmp;
- }
-
- if(comma < max_comma)max_comma = comma;
- /* eliminate the trailing comma */
- if(*line2 == ',') line2++;
+
+ for (comma = 3; comma < 9; comma ++)
+ if (!(line2 = strchr(++line2, ',')))
+ return NULL;
+ line2++;
current->lines=0;num=0;
current->start = 360000*hour1 + 6000*min1 + 100*sec1 + hunsec1;
@@ -701,25 +685,18 @@ static subtitle *sub_read_line_ssa(stream_t *st,subtitle *current,
return current;
}
-static void sub_pp_ssa(subtitle *sub) {
- int l=sub->lines;
- char *so,*de,*start;
-
- while (l){
- /* eliminate any text enclosed with {}, they are font and color settings */
- so=de=sub->text[--l];
- while (*so) {
- if(*so == '{' && so[1]=='\\') {
- for (start=so; *so && *so!='}'; so++);
- if(*so) so++; else so=start;
- }
- if(*so) {
- *de=*so;
- so++; de++;
- }
- }
- *de=*so;
+static void sub_pp_ssa(subtitle *sub)
+{
+ for (int i = 0; i < sub->lines; i++) {
+ char *s, *d;
+ s = d = sub->text[i];
+ while (1) {
+ while (*s == '{')
+ while (*s && *s++ != '}');
+ if (!(*d++ = *s++))
+ break;
}
+ }
}
/*