mirror of
https://github.com/mpv-player/mpv
synced 2024-09-05 02:48:21 +02:00
subassconvert: handle unquoted attributes in subrip font tags
Previously, mplayer didn't convert tags like <font color=#00FF00>. But such subtitles exist in the wild, and should be handled.
This commit is contained in:
parent
aadf1002f8
commit
f0ce95607f
8
bstr.c
8
bstr.c
@ -185,6 +185,14 @@ struct bstr *bstr_splitlines(void *talloc_ctx, struct bstr str)
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool bstr_eatstart(struct bstr *s, struct bstr prefix)
|
||||||
|
{
|
||||||
|
if (!bstr_startswith(*s, prefix))
|
||||||
|
return false;
|
||||||
|
*s = bstr_cut(*s, prefix.len);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void bstr_lower(struct bstr str)
|
void bstr_lower(struct bstr str)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < str.len; i++)
|
for (int i = 0; i < str.len; i++)
|
||||||
|
3
bstr.h
3
bstr.h
@ -82,6 +82,9 @@ int bstr_decode_utf8(struct bstr str, struct bstr *out_next);
|
|||||||
// On error, -1 is returned. On success, it returns a value in the range [1, 4].
|
// On error, -1 is returned. On success, it returns a value in the range [1, 4].
|
||||||
int bstr_parse_utf8_code_length(unsigned char b);
|
int bstr_parse_utf8_code_length(unsigned char b);
|
||||||
|
|
||||||
|
// If s starts with prefix, return true and return the rest of the string in s.
|
||||||
|
bool bstr_eatstart(struct bstr *s, struct bstr prefix);
|
||||||
|
|
||||||
static inline struct bstr bstr_cut(struct bstr str, int n)
|
static inline struct bstr bstr_cut(struct bstr str, int n)
|
||||||
{
|
{
|
||||||
if (n > str.len)
|
if (n > str.len)
|
||||||
|
@ -106,6 +106,27 @@ static const struct {
|
|||||||
|
|
||||||
#define SUBRIP_MAX_STACKED_FONT_TAGS 16
|
#define SUBRIP_MAX_STACKED_FONT_TAGS 16
|
||||||
|
|
||||||
|
/* Read the attribute value starting at *s, and skip *s past the value.
|
||||||
|
* Set out_value to the parsed value, with possible '"' stripped.
|
||||||
|
* Return whether the attribute is well formed. */
|
||||||
|
static bool read_value(char **s, struct bstr *out_value)
|
||||||
|
{
|
||||||
|
char term = 0;
|
||||||
|
if (**s == '"') {
|
||||||
|
term = '"';
|
||||||
|
(*s)++;
|
||||||
|
}
|
||||||
|
out_value->start = *s;
|
||||||
|
out_value->len = 0;
|
||||||
|
unsigned char *start = *s;
|
||||||
|
unsigned char *end = term ? strchr(start, term) : strpbrk(start, " >");
|
||||||
|
if (!end)
|
||||||
|
return false;
|
||||||
|
out_value->len = end - out_value->start;
|
||||||
|
*s = end + (term ? 1 : 0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void subassconvert_subrip(const char *orig, char *dest, int dest_buffer_size)
|
void subassconvert_subrip(const char *orig, char *dest, int dest_buffer_size)
|
||||||
{
|
{
|
||||||
/* line is not const to avoid warnings with strtol, etc.
|
/* line is not const to avoid warnings with strtol, etc.
|
||||||
@ -174,34 +195,35 @@ void subassconvert_subrip(const char *orig, char *dest, int dest_buffer_size)
|
|||||||
line += 6;
|
line += 6;
|
||||||
|
|
||||||
while (*line && *line != '>') {
|
while (*line && *line != '>') {
|
||||||
if (strncmp(line, "size=\"", 6) == 0) {
|
if (strncmp(line, "size=", 5) == 0) {
|
||||||
line += 6;
|
line += 5;
|
||||||
tag->size = strtol(line, &line, 10);
|
struct bstr val;
|
||||||
if (*line != '"')
|
if (!read_value(&line, &val))
|
||||||
|
break;
|
||||||
|
tag->size = bstrtoll(val, &val, 10);
|
||||||
|
if (val.len)
|
||||||
break;
|
break;
|
||||||
append_text(&new_line, "{\\fs%d}", tag->size);
|
append_text(&new_line, "{\\fs%d}", tag->size);
|
||||||
tag->has_size = true;
|
tag->has_size = true;
|
||||||
has_valid_attr = true;
|
has_valid_attr = true;
|
||||||
} else if (strncmp(line, "color=\"", 7) == 0) {
|
} else if (strncmp(line, "color=", 6) == 0) {
|
||||||
line += 7;
|
line += 6;
|
||||||
if (*line == '#') {
|
struct bstr val;
|
||||||
|
if (!read_value(&line, &val))
|
||||||
|
break;
|
||||||
|
if (bstr_eatstart(&val, bstr("#"))) {
|
||||||
// #RRGGBB format
|
// #RRGGBB format
|
||||||
line++;
|
tag->color = bstrtoll(val, &val, 16) & 0x00ffffff;
|
||||||
tag->color = strtol(line, &line, 16) & 0x00ffffff;
|
if (val.len)
|
||||||
if (*line != '"')
|
|
||||||
break;
|
break;
|
||||||
tag->color = ((tag->color & 0xff) << 16)
|
tag->color = ((tag->color & 0xff) << 16)
|
||||||
| (tag->color & 0xff00)
|
| (tag->color & 0xff00)
|
||||||
| ((tag->color & 0xff0000) >> 16);
|
| ((tag->color & 0xff0000) >> 16);
|
||||||
} else {
|
} else {
|
||||||
// Standard web colors
|
// Standard web colors
|
||||||
int len = indexof(line, '"');
|
|
||||||
if (len <= 0)
|
|
||||||
break;
|
|
||||||
for (int i = 0; i < FF_ARRAY_ELEMS(subrip_web_colors); i++) {
|
for (int i = 0; i < FF_ARRAY_ELEMS(subrip_web_colors); i++) {
|
||||||
char *color = subrip_web_colors[i].s;
|
char *color = subrip_web_colors[i].s;
|
||||||
if (strlen(color) == len
|
if (bstrcasecmp(val, bstr(color)) == 0) {
|
||||||
&& strncasecmp(line, color, len) == 0) {
|
|
||||||
tag->color = subrip_web_colors[i].v;
|
tag->color = subrip_web_colors[i].v;
|
||||||
goto foundcolor;
|
goto foundcolor;
|
||||||
}
|
}
|
||||||
@ -211,29 +233,25 @@ void subassconvert_subrip(const char *orig, char *dest, int dest_buffer_size)
|
|||||||
mp_tmsg(MSGT_SUBREADER, MSGL_WARN,
|
mp_tmsg(MSGT_SUBREADER, MSGL_WARN,
|
||||||
"SubRip: unknown font color in subtitle: %s\n", orig);
|
"SubRip: unknown font color in subtitle: %s\n", orig);
|
||||||
append_text(&new_line, "{\\c}");
|
append_text(&new_line, "{\\c}");
|
||||||
line += len + 1;
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
foundcolor:
|
foundcolor: ;
|
||||||
line += len;
|
|
||||||
}
|
}
|
||||||
append_text(&new_line, "{\\c&H%06X&}", tag->color);
|
append_text(&new_line, "{\\c&H%06X&}", tag->color);
|
||||||
tag->has_color = true;
|
tag->has_color = true;
|
||||||
has_valid_attr = true;
|
has_valid_attr = true;
|
||||||
} else if (strncmp(line, "face=\"", 6) == 0) {
|
} else if (strncmp(line, "face=", 5) == 0) {
|
||||||
/* Font face attribute */
|
/* Font face attribute */
|
||||||
line += 6;
|
line += 5;
|
||||||
int len = indexof(line, '"');
|
struct bstr val;
|
||||||
if (len <= 0)
|
if (!read_value(&line, &val))
|
||||||
break;
|
break;
|
||||||
tag->face.start = line;
|
tag->face = val;
|
||||||
tag->face.len = len;
|
|
||||||
line += len;
|
|
||||||
append_text(&new_line, "{\\fn%.*s}", BSTR_P(tag->face));
|
append_text(&new_line, "{\\fn%.*s}", BSTR_P(tag->face));
|
||||||
tag->has_face = true;
|
tag->has_face = true;
|
||||||
has_valid_attr = true;
|
has_valid_attr = true;
|
||||||
}
|
} else
|
||||||
line++;
|
line++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!has_valid_attr || *line != '>') { /* Not valid font tag */
|
if (!has_valid_attr || *line != '>') { /* Not valid font tag */
|
||||||
|
Loading…
Reference in New Issue
Block a user