changeset 32462:6e7c20b56c89

Move subassconvert.[ch] to the sub directory.
author cigaes
date Wed, 27 Oct 2010 17:12:30 +0000
parents bc43cf7638e6
children 7473ed4fca71
files Makefile sub/subassconvert.c sub/subassconvert.h sub/subreader.c subassconvert.c subassconvert.h
diffstat 6 files changed, 548 insertions(+), 548 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Wed Oct 27 17:08:36 2010 +0000
+++ b/Makefile	Wed Oct 27 17:12:30 2010 +0000
@@ -129,7 +129,7 @@
 SRCS_COMMON-$(LIBA52)                += libmpcodecs/ad_liba52.c
 SRCS_COMMON-$(LIBASS)                += libmpcodecs/vf_ass.c \
                                         sub/ass_mp.c \
-                                        subassconvert.c \
+                                        sub/subassconvert.c \
 
 SRCS_COMMON-$(LIBASS_INTERNAL)       += libass/ass.c \
                                         libass/ass_bitmap.c \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sub/subassconvert.c	Wed Oct 27 17:12:30 2010 +0000
@@ -0,0 +1,517 @@
+/*
+ * Subtitles converter to SSA/ASS in order to allow special formatting
+ *
+ * This file is part of MPlayer.
+ *
+ * MPlayer is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * MPlayer is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with MPlayer; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <string.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "mp_msg.h"
+#include "help_mp.h"
+#include "bstr.h"
+#include "sub/subassconvert.h"
+#include "libavutil/common.h"
+
+struct line {
+    char *buf;
+    size_t bufsize;
+    size_t len;
+};
+
+#ifdef __GNUC__
+static void append_text(struct line *dst, char *fmt, ...) __attribute__ ((format(printf, 2, 3)));
+#endif
+
+static void append_text(struct line *dst, char *fmt, ...)
+{
+    va_list va;
+    int ret;
+
+    va_start(va, fmt);
+    ret = vsnprintf(dst->buf + dst->len, dst->bufsize - dst->len, fmt, va);
+    if (ret >= 0) {
+        dst->len += ret;
+        if (dst->len > dst->bufsize)
+            dst->len = dst->bufsize;
+    }
+    va_end(va);
+}
+
+static int indexof(const char *s, int c)
+{
+    char *f = strchr(s, c);
+    return f ? (f - s) : -1;
+}
+
+
+
+/*
+ *      SubRip
+ *
+ *      Support basic tags (italic, bold, underline, strike-through)
+ *      and font tag with size, color and face attributes.
+ *
+ */
+
+struct font_tag {
+    struct bstr face;
+    int size;
+    uint32_t color;
+};
+
+static const struct tag_conv {
+    const char *from;
+    const char *to;
+} subrip_basic_tags[] = {
+    {"<i>", "{\\i1}"}, {"</i>", "{\\i0}"},
+    {"<b>", "{\\b1}"}, {"</b>", "{\\b0}"},
+    {"<u>", "{\\u1}"}, {"</u>", "{\\u0}"},
+    {"<s>", "{\\s1}"}, {"</s>", "{\\s0}"},
+    {"{", "\\{"}, {"}", "\\}"},
+    {"\n", "\\N"}
+};
+
+static const struct {
+    const char *s;
+    uint32_t v;
+} subrip_web_colors[] = {
+    /* 16 named HTML colors in BGR format */
+    {"red",     0x0000ff}, {"blue",   0xff0000}, {"lime",   0x00ff00},
+    {"aqua",    0xffff00}, {"purple", 0x800080}, {"yellow", 0x00ffff},
+    {"fuchsia", 0xff00ff}, {"white",  0xffffff}, {"gray",   0x808080},
+    {"maroon",  0x000080}, {"olive",  0x008080}, {"black",  0x000000},
+    {"silver",  0xc0c0c0}, {"teal",   0x808000}, {"green",  0x008000},
+    {"navy",    0x800000}
+};
+
+#define SUBRIP_MAX_STACKED_FONT_TAGS    16
+#define SUBRIP_FLAG_COLOR               0x01000000
+
+/**
+ * \brief Convert SubRip lines into ASS markup
+ * \param orig original SubRip lines. The content will remain untouched.
+ * \param dest ASS markup destination buffer.
+ * \param dest_buffer_size maximum size for the destination buffer.
+ */
+void subassconvert_subrip(const char *orig, char *dest, size_t dest_buffer_size)
+{
+    /* line is not const to avoid warnings with strtol, etc.
+     * orig content won't be changed */
+    char *line = (char *)orig;
+    struct line new_line = {
+        .buf     = dest,
+        .bufsize = dest_buffer_size,
+    };
+    struct font_tag font_stack[SUBRIP_MAX_STACKED_FONT_TAGS];
+    int sp = 0;
+
+    font_stack[0] = (struct font_tag){}; // type with all defaults
+    while (*line && new_line.len < new_line.bufsize - 1) {
+        char *orig_line = line;
+        int i;
+
+        for (i = 0; i < FF_ARRAY_ELEMS(subrip_basic_tags); i++) {
+            const struct tag_conv *tag = &subrip_basic_tags[i];
+            int from_len = strlen(tag->from);
+            if (strncmp(line, tag->from, from_len) == 0) {
+                append_text(&new_line, "%s", tag->to);
+                line += from_len;
+            }
+        }
+
+        if (strncmp(line, "</font>", 7) == 0) {
+            /* Closing font tag */
+            line += 7;
+
+            if (sp > 0) {
+                struct font_tag *tag      = &font_stack[sp];
+                struct font_tag *last_tag = &tag[-1];
+                sp--;
+
+                if (tag->size) {
+                    if (!last_tag->size)
+                        append_text(&new_line, "{\\fs}");
+                    else if (last_tag->size != tag->size)
+                        append_text(&new_line, "{\\fs%d}", last_tag->size);
+                }
+
+                if (tag->color & SUBRIP_FLAG_COLOR) {
+                    if (!(last_tag->color & SUBRIP_FLAG_COLOR))
+                        append_text(&new_line, "{\\c}");
+                    else if (last_tag->color != tag->color)
+                        append_text(&new_line, "{\\c&H%06X&}",
+                                    last_tag->color & 0xffffff);
+                }
+
+                if (tag->face.len) {
+                    if (!last_tag->face.len)
+                        append_text(&new_line, "{\\fn}");
+                    else if (bstrcmp(last_tag->face, tag->face) != 0)
+                        append_text(&new_line, "{\\fn%.*s}",
+                                    BSTR_P(last_tag->face));
+                }
+            }
+        } else if (strncmp(line, "<font ", 6) == 0
+                   && sp + 1 < FF_ARRAY_ELEMS(font_stack)) {
+            /* Opening font tag */
+            char *potential_font_tag_start = line;
+            int len_backup = new_line.len;
+            struct font_tag *tag = &font_stack[sp + 1];
+            int has_valid_attr = 0;
+
+            *tag = tag[-1]; // keep values from previous tag
+            line += 6;
+
+            while (*line && *line != '>') {
+                if (strncmp(line, "size=\"", 6) == 0) {
+                    line += 6;
+                    tag->size = strtol(line, &line, 10);
+                    if (*line != '"' || !tag->size)
+                        break;
+                    append_text(&new_line, "{\\fs%d}", tag->size);
+                    has_valid_attr = 1;
+                } else if (strncmp(line, "color=\"", 7) == 0) {
+                    line += 7;
+                    if (*line == '#') {
+                        // #RRGGBB format
+                        line++;
+                        tag->color = strtol(line, &line, 16) & 0x00ffffff;
+                        if (*line != '"')
+                            break;
+                        tag->color = ((tag->color & 0xff) << 16) |
+                                      (tag->color & 0xff00) |
+                                     ((tag->color & 0xff0000) >> 16) |
+                                     SUBRIP_FLAG_COLOR;
+                    } else {
+                        // Standard web colors
+                        int i, len = indexof(line, '"');
+                        if (len <= 0)
+                            break;
+                        for (i = 0; i < FF_ARRAY_ELEMS(subrip_web_colors); i++) {
+                            const char *color = subrip_web_colors[i].s;
+                            if (strlen(color) == len
+                                && strncasecmp(line, color, len) == 0) {
+                                tag->color = SUBRIP_FLAG_COLOR | subrip_web_colors[i].v;
+                                break;
+                            }
+                        }
+
+                        if (i == FF_ARRAY_ELEMS(subrip_web_colors)) {
+                            /* We didn't find any matching color */
+                            line = strchr(line, '"'); // can't be NULL, see above
+                            mp_msg(MSGT_SUBREADER, MSGL_WARN,
+                                   MSGTR_SUBTITLES_SubRip_UnknownFontColor, orig);
+                            append_text(&new_line, "{\\c}");
+                            line += 2;
+                            continue;
+                        }
+
+                        line += len;
+                    }
+                    append_text(&new_line, "{\\c&H%06X&}", tag->color & 0xffffff);
+                    has_valid_attr = 1;
+                } else if (strncmp(line, "face=\"", 6) == 0) {
+                    /* Font face attribute */
+                    int len;
+                    line += 6;
+                    len = indexof(line, '"');
+                    if (len <= 0)
+                        break;
+                    tag->face.start = line;
+                    tag->face.len   = len;
+                    line += len;
+                    append_text(&new_line, "{\\fn%.*s}", BSTR_P(tag->face));
+                    has_valid_attr = 1;
+                }
+                line++;
+            }
+
+            if (!has_valid_attr || *line != '>') { /* Not valid font tag */
+                line = potential_font_tag_start;
+                new_line.len = len_backup;
+            } else {
+                sp++;
+                line++;
+            }
+        }
+
+        /* Tag conversion code didn't match */
+        if (line == orig_line)
+            new_line.buf[new_line.len++] = *line++;
+    }
+    new_line.buf[new_line.len] = 0;
+}
+
+
+/*
+ *      MicroDVD
+ *
+ *      Based on the specifications found here:
+ *      https://trac.videolan.org/vlc/ticket/1825#comment:6
+ */
+
+struct microdvd_tag {
+    char key;
+    int persistent;
+    uint32_t data1;
+    uint32_t data2;
+    struct bstr data_string;
+};
+
+#define MICRODVD_PERSISTENT_OFF     0
+#define MICRODVD_PERSISTENT_ON      1
+#define MICRODVD_PERSISTENT_OPENED  2
+
+// Color, Font, Size, cHarset, stYle, Position, cOordinate
+#define MICRODVD_TAGS               "cfshyYpo"
+
+static void microdvd_set_tag(struct microdvd_tag *tags, struct microdvd_tag tag)
+{
+    int tag_index = indexof(MICRODVD_TAGS, tag.key);
+
+    if (tag_index < 0)
+        return;
+    memcpy(&tags[tag_index], &tag, sizeof(tag));
+}
+
+// italic, bold, underline, strike-through
+#define MICRODVD_STYLES             "ibus"
+
+static char *microdvd_load_tags(struct microdvd_tag *tags, char *s)
+{
+    while (*s == '{') {
+        char *start = s;
+        char tag_char = *(s + 1);
+        struct microdvd_tag tag = {};
+
+        if (!tag_char || *(s + 2) != ':')
+            break;
+        s += 3;
+
+        switch (tag_char) {
+
+        /* Style */
+        case 'Y':
+            tag.persistent = MICRODVD_PERSISTENT_ON;
+        case 'y':
+            while (*s && *s != '}') {
+                int style_index = indexof(MICRODVD_STYLES, *s);
+
+                if (style_index >= 0)
+                    tag.data1 |= (1 << style_index);
+                s++;
+            }
+            if (*s != '}')
+                break;
+            /* We must distinguish persistent and non-persistent styles
+             * to handle this kind of style tags: {y:ib}{Y:us} */
+            tag.key = tag_char;
+            break;
+
+        /* Color */
+        case 'C':
+            tag.persistent = MICRODVD_PERSISTENT_ON;
+        case 'c':
+            tag.data1 = strtol(s, &s, 16) & 0x00ffffff;
+            if (*s != '}')
+                break;
+            tag.key = 'c';
+            break;
+
+        /* Font name */
+        case 'F':
+            tag.persistent = MICRODVD_PERSISTENT_ON;
+        case 'f':
+        {
+            int len = indexof(s, '}');
+            if (len < 0)
+                break;
+            tag.data_string.start = s;
+            tag.data_string.len   = len;
+            s += len;
+            tag.key = 'f';
+            break;
+        }
+
+        /* Font size */
+        case 'S':
+            tag.persistent = MICRODVD_PERSISTENT_ON;
+        case 's':
+            tag.data1 = strtol(s, &s, 10);
+            if (*s != '}')
+                break;
+            tag.key = 's';
+            break;
+
+        /* Charset */
+        case 'H':
+        {
+            //TODO: not yet handled, just parsed.
+            int len = indexof(s, '}');
+            if (len < 0)
+                break;
+            tag.data_string.start = s;
+            tag.data_string.len   = len;
+            s += len;
+            tag.key = 'h';
+            break;
+        }
+
+        /* Position */
+        case 'P':
+            tag.persistent = MICRODVD_PERSISTENT_ON;
+            tag.data1 = (*s++ == '1');
+            if (*s != '}')
+                break;
+            tag.key = 'p';
+            break;
+
+        /* Coordinates */
+        case 'o':
+            tag.persistent = MICRODVD_PERSISTENT_ON;
+            tag.data1 = strtol(s, &s, 10);
+            if (*s != ',')
+                break;
+            s++;
+            tag.data2 = strtol(s, &s, 10);
+            if (*s != '}')
+                break;
+            tag.key = 'o';
+            break;
+
+        default:    /* Unknown tag, we consider it's text */
+            break;
+        }
+
+        if (tag.key == 0)
+            return start;
+
+        microdvd_set_tag(tags, tag);
+        s++;
+    }
+    return s;
+}
+
+static void microdvd_open_tags(struct line *new_line, struct microdvd_tag *tags)
+{
+    int i, sidx;
+    for (i = 0; i < sizeof(MICRODVD_TAGS) - 1; i++) {
+        if (tags[i].persistent == MICRODVD_PERSISTENT_OPENED)
+            continue;
+        switch (tags[i].key) {
+        case 'Y':
+        case 'y':
+            for (sidx = 0; sidx < sizeof(MICRODVD_STYLES) - 1; sidx++)
+                if (tags[i].data1 & (1 << sidx))
+                    append_text(new_line, "{\\%c1}", MICRODVD_STYLES[sidx]);
+            break;
+
+        case 'c':
+            append_text(new_line, "{\\c&H%06X&}", tags[i].data1);
+            break;
+
+        case 'f':
+            append_text(new_line, "{\\fn%.*s}", BSTR_P(tags[i].data_string));
+            break;
+
+        case 's':
+            append_text(new_line, "{\\fs%d}", tags[i].data1);
+            break;
+
+        case 'p':
+            if (tags[i].data1 == 0)
+                append_text(new_line, "{\\an8}");
+            break;
+
+        case 'o':
+            append_text(new_line, "{\\pos(%d,%d)}",
+                        tags[i].data1, tags[i].data2);
+            break;
+        }
+        if (tags[i].persistent == MICRODVD_PERSISTENT_ON)
+            tags[i].persistent = MICRODVD_PERSISTENT_OPENED;
+    }
+}
+
+static void microdvd_close_no_persistent_tags(struct line *new_line,
+                                              struct microdvd_tag *tags)
+{
+    int i, sidx;
+
+    for (i = sizeof(MICRODVD_TAGS) - 2; i; i--) {
+        if (tags[i].persistent != MICRODVD_PERSISTENT_OFF)
+            continue;
+        switch (tags[i].key) {
+
+        case 'y':
+            for (sidx = sizeof(MICRODVD_STYLES) - 2; sidx >= 0; sidx--)
+                if (tags[i].data1 & (1 << sidx))
+                    append_text(new_line, "{\\%c0}", MICRODVD_STYLES[sidx]);
+            break;
+
+        case 'c':
+            append_text(new_line, "{\\c}");
+            break;
+
+        case 'f':
+            append_text(new_line, "{\\fn}");
+            break;
+
+        case 's':
+            append_text(new_line, "{\\fs}");
+            break;
+        }
+        tags[i].key = 0;
+    }
+}
+
+/**
+ * \brief Convert MicroDVD lines into ASS markup
+ * \param orig original MicroDVD line. The content will remain untouched.
+ * \param dest ASS markup destination buffer.
+ * \param dest_buffer_size maximum size for the destination buffer.
+ */
+void subassconvert_microdvd(const char *orig, char *dest, size_t dest_buffer_size)
+{
+    /* line is not const to avoid warnings with strtol, etc.
+     * orig content won't be changed */
+    char *line = (char *)orig;
+    struct line new_line = {
+        .buf     = dest,
+        .bufsize = dest_buffer_size,
+    };
+    struct microdvd_tag tags[sizeof(MICRODVD_TAGS) - 1] = {};
+
+    while (*line) {
+        line = microdvd_load_tags(tags, line);
+        microdvd_open_tags(&new_line, tags);
+
+        while (*line && *line != '|')
+            new_line.buf[new_line.len++] = *line++;
+
+        if (*line == '|') {
+            microdvd_close_no_persistent_tags(&new_line, tags);
+            append_text(&new_line, "\\N");
+            line++;
+        }
+    }
+    new_line.buf[new_line.len] = 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sub/subassconvert.h	Wed Oct 27 17:12:30 2010 +0000
@@ -0,0 +1,29 @@
+/*
+ * Header for subtitles converter to SSA/ASS
+ *
+ * This file is part of MPlayer.
+ *
+ * MPlayer is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * MPlayer is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with MPlayer; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef MPLAYER_SUBASSCONVERT_H
+#define MPLAYER_SUBASSCONVERT_H
+
+#include <sys/types.h>
+
+void subassconvert_subrip(const char *orig, char *dest, size_t dest_buffer_size);
+void subassconvert_microdvd(const char *orig, char *dest, size_t dest_buffer_size);
+
+#endif
--- a/sub/subreader.c	Wed Oct 27 17:08:36 2010 +0000
+++ b/sub/subreader.c	Wed Oct 27 17:12:30 2010 +0000
@@ -34,7 +34,7 @@
 #include "mp_msg.h"
 #include "mpcommon.h"
 #include "sub/subreader.h"
-#include "subassconvert.h"
+#include "sub/subassconvert.h"
 #include "libvo/sub.h"
 #include "stream/stream.h"
 #include "libavutil/common.h"
--- a/subassconvert.c	Wed Oct 27 17:08:36 2010 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,517 +0,0 @@
-/*
- * Subtitles converter to SSA/ASS in order to allow special formatting
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <string.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#include "mp_msg.h"
-#include "help_mp.h"
-#include "bstr.h"
-#include "subassconvert.h"
-#include "libavutil/common.h"
-
-struct line {
-    char *buf;
-    size_t bufsize;
-    size_t len;
-};
-
-#ifdef __GNUC__
-static void append_text(struct line *dst, char *fmt, ...) __attribute__ ((format(printf, 2, 3)));
-#endif
-
-static void append_text(struct line *dst, char *fmt, ...)
-{
-    va_list va;
-    int ret;
-
-    va_start(va, fmt);
-    ret = vsnprintf(dst->buf + dst->len, dst->bufsize - dst->len, fmt, va);
-    if (ret >= 0) {
-        dst->len += ret;
-        if (dst->len > dst->bufsize)
-            dst->len = dst->bufsize;
-    }
-    va_end(va);
-}
-
-static int indexof(const char *s, int c)
-{
-    char *f = strchr(s, c);
-    return f ? (f - s) : -1;
-}
-
-
-
-/*
- *      SubRip
- *
- *      Support basic tags (italic, bold, underline, strike-through)
- *      and font tag with size, color and face attributes.
- *
- */
-
-struct font_tag {
-    struct bstr face;
-    int size;
-    uint32_t color;
-};
-
-static const struct tag_conv {
-    const char *from;
-    const char *to;
-} subrip_basic_tags[] = {
-    {"<i>", "{\\i1}"}, {"</i>", "{\\i0}"},
-    {"<b>", "{\\b1}"}, {"</b>", "{\\b0}"},
-    {"<u>", "{\\u1}"}, {"</u>", "{\\u0}"},
-    {"<s>", "{\\s1}"}, {"</s>", "{\\s0}"},
-    {"{", "\\{"}, {"}", "\\}"},
-    {"\n", "\\N"}
-};
-
-static const struct {
-    const char *s;
-    uint32_t v;
-} subrip_web_colors[] = {
-    /* 16 named HTML colors in BGR format */
-    {"red",     0x0000ff}, {"blue",   0xff0000}, {"lime",   0x00ff00},
-    {"aqua",    0xffff00}, {"purple", 0x800080}, {"yellow", 0x00ffff},
-    {"fuchsia", 0xff00ff}, {"white",  0xffffff}, {"gray",   0x808080},
-    {"maroon",  0x000080}, {"olive",  0x008080}, {"black",  0x000000},
-    {"silver",  0xc0c0c0}, {"teal",   0x808000}, {"green",  0x008000},
-    {"navy",    0x800000}
-};
-
-#define SUBRIP_MAX_STACKED_FONT_TAGS    16
-#define SUBRIP_FLAG_COLOR               0x01000000
-
-/**
- * \brief Convert SubRip lines into ASS markup
- * \param orig original SubRip lines. The content will remain untouched.
- * \param dest ASS markup destination buffer.
- * \param dest_buffer_size maximum size for the destination buffer.
- */
-void subassconvert_subrip(const char *orig, char *dest, size_t dest_buffer_size)
-{
-    /* line is not const to avoid warnings with strtol, etc.
-     * orig content won't be changed */
-    char *line = (char *)orig;
-    struct line new_line = {
-        .buf     = dest,
-        .bufsize = dest_buffer_size,
-    };
-    struct font_tag font_stack[SUBRIP_MAX_STACKED_FONT_TAGS];
-    int sp = 0;
-
-    font_stack[0] = (struct font_tag){}; // type with all defaults
-    while (*line && new_line.len < new_line.bufsize - 1) {
-        char *orig_line = line;
-        int i;
-
-        for (i = 0; i < FF_ARRAY_ELEMS(subrip_basic_tags); i++) {
-            const struct tag_conv *tag = &subrip_basic_tags[i];
-            int from_len = strlen(tag->from);
-            if (strncmp(line, tag->from, from_len) == 0) {
-                append_text(&new_line, "%s", tag->to);
-                line += from_len;
-            }
-        }
-
-        if (strncmp(line, "</font>", 7) == 0) {
-            /* Closing font tag */
-            line += 7;
-
-            if (sp > 0) {
-                struct font_tag *tag      = &font_stack[sp];
-                struct font_tag *last_tag = &tag[-1];
-                sp--;
-
-                if (tag->size) {
-                    if (!last_tag->size)
-                        append_text(&new_line, "{\\fs}");
-                    else if (last_tag->size != tag->size)
-                        append_text(&new_line, "{\\fs%d}", last_tag->size);
-                }
-
-                if (tag->color & SUBRIP_FLAG_COLOR) {
-                    if (!(last_tag->color & SUBRIP_FLAG_COLOR))
-                        append_text(&new_line, "{\\c}");
-                    else if (last_tag->color != tag->color)
-                        append_text(&new_line, "{\\c&H%06X&}",
-                                    last_tag->color & 0xffffff);
-                }
-
-                if (tag->face.len) {
-                    if (!last_tag->face.len)
-                        append_text(&new_line, "{\\fn}");
-                    else if (bstrcmp(last_tag->face, tag->face) != 0)
-                        append_text(&new_line, "{\\fn%.*s}",
-                                    BSTR_P(last_tag->face));
-                }
-            }
-        } else if (strncmp(line, "<font ", 6) == 0
-                   && sp + 1 < FF_ARRAY_ELEMS(font_stack)) {
-            /* Opening font tag */
-            char *potential_font_tag_start = line;
-            int len_backup = new_line.len;
-            struct font_tag *tag = &font_stack[sp + 1];
-            int has_valid_attr = 0;
-
-            *tag = tag[-1]; // keep values from previous tag
-            line += 6;
-
-            while (*line && *line != '>') {
-                if (strncmp(line, "size=\"", 6) == 0) {
-                    line += 6;
-                    tag->size = strtol(line, &line, 10);
-                    if (*line != '"' || !tag->size)
-                        break;
-                    append_text(&new_line, "{\\fs%d}", tag->size);
-                    has_valid_attr = 1;
-                } else if (strncmp(line, "color=\"", 7) == 0) {
-                    line += 7;
-                    if (*line == '#') {
-                        // #RRGGBB format
-                        line++;
-                        tag->color = strtol(line, &line, 16) & 0x00ffffff;
-                        if (*line != '"')
-                            break;
-                        tag->color = ((tag->color & 0xff) << 16) |
-                                      (tag->color & 0xff00) |
-                                     ((tag->color & 0xff0000) >> 16) |
-                                     SUBRIP_FLAG_COLOR;
-                    } else {
-                        // Standard web colors
-                        int i, len = indexof(line, '"');
-                        if (len <= 0)
-                            break;
-                        for (i = 0; i < FF_ARRAY_ELEMS(subrip_web_colors); i++) {
-                            const char *color = subrip_web_colors[i].s;
-                            if (strlen(color) == len
-                                && strncasecmp(line, color, len) == 0) {
-                                tag->color = SUBRIP_FLAG_COLOR | subrip_web_colors[i].v;
-                                break;
-                            }
-                        }
-
-                        if (i == FF_ARRAY_ELEMS(subrip_web_colors)) {
-                            /* We didn't find any matching color */
-                            line = strchr(line, '"'); // can't be NULL, see above
-                            mp_msg(MSGT_SUBREADER, MSGL_WARN,
-                                   MSGTR_SUBTITLES_SubRip_UnknownFontColor, orig);
-                            append_text(&new_line, "{\\c}");
-                            line += 2;
-                            continue;
-                        }
-
-                        line += len;
-                    }
-                    append_text(&new_line, "{\\c&H%06X&}", tag->color & 0xffffff);
-                    has_valid_attr = 1;
-                } else if (strncmp(line, "face=\"", 6) == 0) {
-                    /* Font face attribute */
-                    int len;
-                    line += 6;
-                    len = indexof(line, '"');
-                    if (len <= 0)
-                        break;
-                    tag->face.start = line;
-                    tag->face.len   = len;
-                    line += len;
-                    append_text(&new_line, "{\\fn%.*s}", BSTR_P(tag->face));
-                    has_valid_attr = 1;
-                }
-                line++;
-            }
-
-            if (!has_valid_attr || *line != '>') { /* Not valid font tag */
-                line = potential_font_tag_start;
-                new_line.len = len_backup;
-            } else {
-                sp++;
-                line++;
-            }
-        }
-
-        /* Tag conversion code didn't match */
-        if (line == orig_line)
-            new_line.buf[new_line.len++] = *line++;
-    }
-    new_line.buf[new_line.len] = 0;
-}
-
-
-/*
- *      MicroDVD
- *
- *      Based on the specifications found here:
- *      https://trac.videolan.org/vlc/ticket/1825#comment:6
- */
-
-struct microdvd_tag {
-    char key;
-    int persistent;
-    uint32_t data1;
-    uint32_t data2;
-    struct bstr data_string;
-};
-
-#define MICRODVD_PERSISTENT_OFF     0
-#define MICRODVD_PERSISTENT_ON      1
-#define MICRODVD_PERSISTENT_OPENED  2
-
-// Color, Font, Size, cHarset, stYle, Position, cOordinate
-#define MICRODVD_TAGS               "cfshyYpo"
-
-static void microdvd_set_tag(struct microdvd_tag *tags, struct microdvd_tag tag)
-{
-    int tag_index = indexof(MICRODVD_TAGS, tag.key);
-
-    if (tag_index < 0)
-        return;
-    memcpy(&tags[tag_index], &tag, sizeof(tag));
-}
-
-// italic, bold, underline, strike-through
-#define MICRODVD_STYLES             "ibus"
-
-static char *microdvd_load_tags(struct microdvd_tag *tags, char *s)
-{
-    while (*s == '{') {
-        char *start = s;
-        char tag_char = *(s + 1);
-        struct microdvd_tag tag = {};
-
-        if (!tag_char || *(s + 2) != ':')
-            break;
-        s += 3;
-
-        switch (tag_char) {
-
-        /* Style */
-        case 'Y':
-            tag.persistent = MICRODVD_PERSISTENT_ON;
-        case 'y':
-            while (*s && *s != '}') {
-                int style_index = indexof(MICRODVD_STYLES, *s);
-
-                if (style_index >= 0)
-                    tag.data1 |= (1 << style_index);
-                s++;
-            }
-            if (*s != '}')
-                break;
-            /* We must distinguish persistent and non-persistent styles
-             * to handle this kind of style tags: {y:ib}{Y:us} */
-            tag.key = tag_char;
-            break;
-
-        /* Color */
-        case 'C':
-            tag.persistent = MICRODVD_PERSISTENT_ON;
-        case 'c':
-            tag.data1 = strtol(s, &s, 16) & 0x00ffffff;
-            if (*s != '}')
-                break;
-            tag.key = 'c';
-            break;
-
-        /* Font name */
-        case 'F':
-            tag.persistent = MICRODVD_PERSISTENT_ON;
-        case 'f':
-        {
-            int len = indexof(s, '}');
-            if (len < 0)
-                break;
-            tag.data_string.start = s;
-            tag.data_string.len   = len;
-            s += len;
-            tag.key = 'f';
-            break;
-        }
-
-        /* Font size */
-        case 'S':
-            tag.persistent = MICRODVD_PERSISTENT_ON;
-        case 's':
-            tag.data1 = strtol(s, &s, 10);
-            if (*s != '}')
-                break;
-            tag.key = 's';
-            break;
-
-        /* Charset */
-        case 'H':
-        {
-            //TODO: not yet handled, just parsed.
-            int len = indexof(s, '}');
-            if (len < 0)
-                break;
-            tag.data_string.start = s;
-            tag.data_string.len   = len;
-            s += len;
-            tag.key = 'h';
-            break;
-        }
-
-        /* Position */
-        case 'P':
-            tag.persistent = MICRODVD_PERSISTENT_ON;
-            tag.data1 = (*s++ == '1');
-            if (*s != '}')
-                break;
-            tag.key = 'p';
-            break;
-
-        /* Coordinates */
-        case 'o':
-            tag.persistent = MICRODVD_PERSISTENT_ON;
-            tag.data1 = strtol(s, &s, 10);
-            if (*s != ',')
-                break;
-            s++;
-            tag.data2 = strtol(s, &s, 10);
-            if (*s != '}')
-                break;
-            tag.key = 'o';
-            break;
-
-        default:    /* Unknown tag, we consider it's text */
-            break;
-        }
-
-        if (tag.key == 0)
-            return start;
-
-        microdvd_set_tag(tags, tag);
-        s++;
-    }
-    return s;
-}
-
-static void microdvd_open_tags(struct line *new_line, struct microdvd_tag *tags)
-{
-    int i, sidx;
-    for (i = 0; i < sizeof(MICRODVD_TAGS) - 1; i++) {
-        if (tags[i].persistent == MICRODVD_PERSISTENT_OPENED)
-            continue;
-        switch (tags[i].key) {
-        case 'Y':
-        case 'y':
-            for (sidx = 0; sidx < sizeof(MICRODVD_STYLES) - 1; sidx++)
-                if (tags[i].data1 & (1 << sidx))
-                    append_text(new_line, "{\\%c1}", MICRODVD_STYLES[sidx]);
-            break;
-
-        case 'c':
-            append_text(new_line, "{\\c&H%06X&}", tags[i].data1);
-            break;
-
-        case 'f':
-            append_text(new_line, "{\\fn%.*s}", BSTR_P(tags[i].data_string));
-            break;
-
-        case 's':
-            append_text(new_line, "{\\fs%d}", tags[i].data1);
-            break;
-
-        case 'p':
-            if (tags[i].data1 == 0)
-                append_text(new_line, "{\\an8}");
-            break;
-
-        case 'o':
-            append_text(new_line, "{\\pos(%d,%d)}",
-                        tags[i].data1, tags[i].data2);
-            break;
-        }
-        if (tags[i].persistent == MICRODVD_PERSISTENT_ON)
-            tags[i].persistent = MICRODVD_PERSISTENT_OPENED;
-    }
-}
-
-static void microdvd_close_no_persistent_tags(struct line *new_line,
-                                              struct microdvd_tag *tags)
-{
-    int i, sidx;
-
-    for (i = sizeof(MICRODVD_TAGS) - 2; i; i--) {
-        if (tags[i].persistent != MICRODVD_PERSISTENT_OFF)
-            continue;
-        switch (tags[i].key) {
-
-        case 'y':
-            for (sidx = sizeof(MICRODVD_STYLES) - 2; sidx >= 0; sidx--)
-                if (tags[i].data1 & (1 << sidx))
-                    append_text(new_line, "{\\%c0}", MICRODVD_STYLES[sidx]);
-            break;
-
-        case 'c':
-            append_text(new_line, "{\\c}");
-            break;
-
-        case 'f':
-            append_text(new_line, "{\\fn}");
-            break;
-
-        case 's':
-            append_text(new_line, "{\\fs}");
-            break;
-        }
-        tags[i].key = 0;
-    }
-}
-
-/**
- * \brief Convert MicroDVD lines into ASS markup
- * \param orig original MicroDVD line. The content will remain untouched.
- * \param dest ASS markup destination buffer.
- * \param dest_buffer_size maximum size for the destination buffer.
- */
-void subassconvert_microdvd(const char *orig, char *dest, size_t dest_buffer_size)
-{
-    /* line is not const to avoid warnings with strtol, etc.
-     * orig content won't be changed */
-    char *line = (char *)orig;
-    struct line new_line = {
-        .buf     = dest,
-        .bufsize = dest_buffer_size,
-    };
-    struct microdvd_tag tags[sizeof(MICRODVD_TAGS) - 1] = {};
-
-    while (*line) {
-        line = microdvd_load_tags(tags, line);
-        microdvd_open_tags(&new_line, tags);
-
-        while (*line && *line != '|')
-            new_line.buf[new_line.len++] = *line++;
-
-        if (*line == '|') {
-            microdvd_close_no_persistent_tags(&new_line, tags);
-            append_text(&new_line, "\\N");
-            line++;
-        }
-    }
-    new_line.buf[new_line.len] = 0;
-}
--- a/subassconvert.h	Wed Oct 27 17:08:36 2010 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-/*
- * Header for subtitles converter to SSA/ASS
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef MPLAYER_SUBASSCONVERT_H
-#define MPLAYER_SUBASSCONVERT_H
-
-#include <sys/types.h>
-
-void subassconvert_subrip(const char *orig, char *dest, size_t dest_buffer_size);
-void subassconvert_microdvd(const char *orig, char *dest, size_t dest_buffer_size);
-
-#endif