annotate sub/subassconvert.c @ 32525:11b0a82d018c

Simplify: Use early return instead of large if block.
author reimar
date Tue, 09 Nov 2010 22:13:11 +0000
parents 22888a8cb312
children da38eb1e2069
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
32462
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
1 /*
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
2 * Subtitles converter to SSA/ASS in order to allow special formatting
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
3 *
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
4 * This file is part of MPlayer.
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
5 *
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
6 * MPlayer is free software; you can redistribute it and/or modify
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
7 * it under the terms of the GNU General Public License as published by
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
8 * the Free Software Foundation; either version 2 of the License, or
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
9 * (at your option) any later version.
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
10 *
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
11 * MPlayer is distributed in the hope that it will be useful,
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
14 * GNU General Public License for more details.
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
15 *
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
16 * You should have received a copy of the GNU General Public License along
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
17 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
19 */
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
20
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
21 #include <string.h>
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
22 #include <stdint.h>
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
23 #include <stdlib.h>
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
24 #include <stdio.h>
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
25 #include <stdarg.h>
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
26
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
27 #include "mp_msg.h"
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
28 #include "help_mp.h"
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
29 #include "bstr.h"
32464
22888a8cb312 Do not use a path for including files in the same directory.
reimar
parents: 32462
diff changeset
30 #include "subassconvert.h"
32462
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
31 #include "libavutil/common.h"
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
32
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
33 struct line {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
34 char *buf;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
35 size_t bufsize;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
36 size_t len;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
37 };
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
38
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
39 #ifdef __GNUC__
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
40 static void append_text(struct line *dst, char *fmt, ...) __attribute__ ((format(printf, 2, 3)));
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
41 #endif
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
42
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
43 static void append_text(struct line *dst, char *fmt, ...)
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
44 {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
45 va_list va;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
46 int ret;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
47
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
48 va_start(va, fmt);
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
49 ret = vsnprintf(dst->buf + dst->len, dst->bufsize - dst->len, fmt, va);
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
50 if (ret >= 0) {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
51 dst->len += ret;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
52 if (dst->len > dst->bufsize)
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
53 dst->len = dst->bufsize;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
54 }
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
55 va_end(va);
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
56 }
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
57
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
58 static int indexof(const char *s, int c)
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
59 {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
60 char *f = strchr(s, c);
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
61 return f ? (f - s) : -1;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
62 }
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
63
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
64
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
65
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
66 /*
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
67 * SubRip
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
68 *
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
69 * Support basic tags (italic, bold, underline, strike-through)
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
70 * and font tag with size, color and face attributes.
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
71 *
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
72 */
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
73
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
74 struct font_tag {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
75 struct bstr face;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
76 int size;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
77 uint32_t color;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
78 };
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
79
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
80 static const struct tag_conv {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
81 const char *from;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
82 const char *to;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
83 } subrip_basic_tags[] = {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
84 {"<i>", "{\\i1}"}, {"</i>", "{\\i0}"},
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
85 {"<b>", "{\\b1}"}, {"</b>", "{\\b0}"},
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
86 {"<u>", "{\\u1}"}, {"</u>", "{\\u0}"},
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
87 {"<s>", "{\\s1}"}, {"</s>", "{\\s0}"},
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
88 {"{", "\\{"}, {"}", "\\}"},
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
89 {"\n", "\\N"}
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
90 };
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
91
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
92 static const struct {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
93 const char *s;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
94 uint32_t v;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
95 } subrip_web_colors[] = {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
96 /* 16 named HTML colors in BGR format */
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
97 {"red", 0x0000ff}, {"blue", 0xff0000}, {"lime", 0x00ff00},
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
98 {"aqua", 0xffff00}, {"purple", 0x800080}, {"yellow", 0x00ffff},
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
99 {"fuchsia", 0xff00ff}, {"white", 0xffffff}, {"gray", 0x808080},
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
100 {"maroon", 0x000080}, {"olive", 0x008080}, {"black", 0x000000},
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
101 {"silver", 0xc0c0c0}, {"teal", 0x808000}, {"green", 0x008000},
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
102 {"navy", 0x800000}
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
103 };
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
104
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
105 #define SUBRIP_MAX_STACKED_FONT_TAGS 16
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
106 #define SUBRIP_FLAG_COLOR 0x01000000
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
107
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
108 /**
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
109 * \brief Convert SubRip lines into ASS markup
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
110 * \param orig original SubRip lines. The content will remain untouched.
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
111 * \param dest ASS markup destination buffer.
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
112 * \param dest_buffer_size maximum size for the destination buffer.
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
113 */
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
114 void subassconvert_subrip(const char *orig, char *dest, size_t dest_buffer_size)
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
115 {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
116 /* line is not const to avoid warnings with strtol, etc.
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
117 * orig content won't be changed */
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
118 char *line = (char *)orig;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
119 struct line new_line = {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
120 .buf = dest,
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
121 .bufsize = dest_buffer_size,
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
122 };
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
123 struct font_tag font_stack[SUBRIP_MAX_STACKED_FONT_TAGS];
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
124 int sp = 0;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
125
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
126 font_stack[0] = (struct font_tag){}; // type with all defaults
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
127 while (*line && new_line.len < new_line.bufsize - 1) {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
128 char *orig_line = line;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
129 int i;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
130
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
131 for (i = 0; i < FF_ARRAY_ELEMS(subrip_basic_tags); i++) {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
132 const struct tag_conv *tag = &subrip_basic_tags[i];
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
133 int from_len = strlen(tag->from);
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
134 if (strncmp(line, tag->from, from_len) == 0) {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
135 append_text(&new_line, "%s", tag->to);
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
136 line += from_len;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
137 }
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
138 }
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
139
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
140 if (strncmp(line, "</font>", 7) == 0) {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
141 /* Closing font tag */
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
142 line += 7;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
143
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
144 if (sp > 0) {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
145 struct font_tag *tag = &font_stack[sp];
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
146 struct font_tag *last_tag = &tag[-1];
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
147 sp--;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
148
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
149 if (tag->size) {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
150 if (!last_tag->size)
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
151 append_text(&new_line, "{\\fs}");
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
152 else if (last_tag->size != tag->size)
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
153 append_text(&new_line, "{\\fs%d}", last_tag->size);
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
154 }
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
155
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
156 if (tag->color & SUBRIP_FLAG_COLOR) {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
157 if (!(last_tag->color & SUBRIP_FLAG_COLOR))
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
158 append_text(&new_line, "{\\c}");
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
159 else if (last_tag->color != tag->color)
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
160 append_text(&new_line, "{\\c&H%06X&}",
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
161 last_tag->color & 0xffffff);
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
162 }
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
163
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
164 if (tag->face.len) {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
165 if (!last_tag->face.len)
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
166 append_text(&new_line, "{\\fn}");
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
167 else if (bstrcmp(last_tag->face, tag->face) != 0)
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
168 append_text(&new_line, "{\\fn%.*s}",
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
169 BSTR_P(last_tag->face));
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
170 }
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
171 }
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
172 } else if (strncmp(line, "<font ", 6) == 0
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
173 && sp + 1 < FF_ARRAY_ELEMS(font_stack)) {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
174 /* Opening font tag */
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
175 char *potential_font_tag_start = line;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
176 int len_backup = new_line.len;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
177 struct font_tag *tag = &font_stack[sp + 1];
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
178 int has_valid_attr = 0;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
179
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
180 *tag = tag[-1]; // keep values from previous tag
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
181 line += 6;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
182
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
183 while (*line && *line != '>') {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
184 if (strncmp(line, "size=\"", 6) == 0) {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
185 line += 6;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
186 tag->size = strtol(line, &line, 10);
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
187 if (*line != '"' || !tag->size)
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
188 break;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
189 append_text(&new_line, "{\\fs%d}", tag->size);
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
190 has_valid_attr = 1;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
191 } else if (strncmp(line, "color=\"", 7) == 0) {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
192 line += 7;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
193 if (*line == '#') {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
194 // #RRGGBB format
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
195 line++;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
196 tag->color = strtol(line, &line, 16) & 0x00ffffff;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
197 if (*line != '"')
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
198 break;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
199 tag->color = ((tag->color & 0xff) << 16) |
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
200 (tag->color & 0xff00) |
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
201 ((tag->color & 0xff0000) >> 16) |
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
202 SUBRIP_FLAG_COLOR;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
203 } else {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
204 // Standard web colors
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
205 int i, len = indexof(line, '"');
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
206 if (len <= 0)
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
207 break;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
208 for (i = 0; i < FF_ARRAY_ELEMS(subrip_web_colors); i++) {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
209 const char *color = subrip_web_colors[i].s;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
210 if (strlen(color) == len
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
211 && strncasecmp(line, color, len) == 0) {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
212 tag->color = SUBRIP_FLAG_COLOR | subrip_web_colors[i].v;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
213 break;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
214 }
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
215 }
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
216
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
217 if (i == FF_ARRAY_ELEMS(subrip_web_colors)) {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
218 /* We didn't find any matching color */
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
219 line = strchr(line, '"'); // can't be NULL, see above
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
220 mp_msg(MSGT_SUBREADER, MSGL_WARN,
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
221 MSGTR_SUBTITLES_SubRip_UnknownFontColor, orig);
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
222 append_text(&new_line, "{\\c}");
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
223 line += 2;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
224 continue;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
225 }
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
226
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
227 line += len;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
228 }
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
229 append_text(&new_line, "{\\c&H%06X&}", tag->color & 0xffffff);
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
230 has_valid_attr = 1;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
231 } else if (strncmp(line, "face=\"", 6) == 0) {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
232 /* Font face attribute */
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
233 int len;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
234 line += 6;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
235 len = indexof(line, '"');
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
236 if (len <= 0)
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
237 break;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
238 tag->face.start = line;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
239 tag->face.len = len;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
240 line += len;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
241 append_text(&new_line, "{\\fn%.*s}", BSTR_P(tag->face));
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
242 has_valid_attr = 1;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
243 }
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
244 line++;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
245 }
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
246
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
247 if (!has_valid_attr || *line != '>') { /* Not valid font tag */
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
248 line = potential_font_tag_start;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
249 new_line.len = len_backup;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
250 } else {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
251 sp++;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
252 line++;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
253 }
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
254 }
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
255
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
256 /* Tag conversion code didn't match */
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
257 if (line == orig_line)
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
258 new_line.buf[new_line.len++] = *line++;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
259 }
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
260 new_line.buf[new_line.len] = 0;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
261 }
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
262
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
263
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
264 /*
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
265 * MicroDVD
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
266 *
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
267 * Based on the specifications found here:
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
268 * https://trac.videolan.org/vlc/ticket/1825#comment:6
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
269 */
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
270
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
271 struct microdvd_tag {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
272 char key;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
273 int persistent;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
274 uint32_t data1;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
275 uint32_t data2;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
276 struct bstr data_string;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
277 };
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
278
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
279 #define MICRODVD_PERSISTENT_OFF 0
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
280 #define MICRODVD_PERSISTENT_ON 1
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
281 #define MICRODVD_PERSISTENT_OPENED 2
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
282
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
283 // Color, Font, Size, cHarset, stYle, Position, cOordinate
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
284 #define MICRODVD_TAGS "cfshyYpo"
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
285
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
286 static void microdvd_set_tag(struct microdvd_tag *tags, struct microdvd_tag tag)
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
287 {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
288 int tag_index = indexof(MICRODVD_TAGS, tag.key);
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
289
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
290 if (tag_index < 0)
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
291 return;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
292 memcpy(&tags[tag_index], &tag, sizeof(tag));
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
293 }
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
294
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
295 // italic, bold, underline, strike-through
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
296 #define MICRODVD_STYLES "ibus"
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
297
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
298 static char *microdvd_load_tags(struct microdvd_tag *tags, char *s)
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
299 {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
300 while (*s == '{') {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
301 char *start = s;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
302 char tag_char = *(s + 1);
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
303 struct microdvd_tag tag = {};
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
304
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
305 if (!tag_char || *(s + 2) != ':')
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
306 break;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
307 s += 3;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
308
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
309 switch (tag_char) {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
310
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
311 /* Style */
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
312 case 'Y':
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
313 tag.persistent = MICRODVD_PERSISTENT_ON;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
314 case 'y':
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
315 while (*s && *s != '}') {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
316 int style_index = indexof(MICRODVD_STYLES, *s);
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
317
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
318 if (style_index >= 0)
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
319 tag.data1 |= (1 << style_index);
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
320 s++;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
321 }
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
322 if (*s != '}')
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
323 break;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
324 /* We must distinguish persistent and non-persistent styles
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
325 * to handle this kind of style tags: {y:ib}{Y:us} */
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
326 tag.key = tag_char;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
327 break;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
328
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
329 /* Color */
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
330 case 'C':
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
331 tag.persistent = MICRODVD_PERSISTENT_ON;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
332 case 'c':
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
333 tag.data1 = strtol(s, &s, 16) & 0x00ffffff;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
334 if (*s != '}')
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
335 break;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
336 tag.key = 'c';
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
337 break;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
338
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
339 /* Font name */
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
340 case 'F':
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
341 tag.persistent = MICRODVD_PERSISTENT_ON;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
342 case 'f':
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
343 {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
344 int len = indexof(s, '}');
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
345 if (len < 0)
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
346 break;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
347 tag.data_string.start = s;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
348 tag.data_string.len = len;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
349 s += len;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
350 tag.key = 'f';
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
351 break;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
352 }
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
353
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
354 /* Font size */
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
355 case 'S':
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
356 tag.persistent = MICRODVD_PERSISTENT_ON;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
357 case 's':
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
358 tag.data1 = strtol(s, &s, 10);
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
359 if (*s != '}')
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
360 break;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
361 tag.key = 's';
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
362 break;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
363
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
364 /* Charset */
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
365 case 'H':
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
366 {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
367 //TODO: not yet handled, just parsed.
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
368 int len = indexof(s, '}');
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
369 if (len < 0)
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
370 break;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
371 tag.data_string.start = s;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
372 tag.data_string.len = len;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
373 s += len;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
374 tag.key = 'h';
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
375 break;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
376 }
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
377
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
378 /* Position */
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
379 case 'P':
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
380 tag.persistent = MICRODVD_PERSISTENT_ON;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
381 tag.data1 = (*s++ == '1');
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
382 if (*s != '}')
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
383 break;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
384 tag.key = 'p';
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
385 break;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
386
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
387 /* Coordinates */
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
388 case 'o':
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
389 tag.persistent = MICRODVD_PERSISTENT_ON;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
390 tag.data1 = strtol(s, &s, 10);
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
391 if (*s != ',')
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
392 break;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
393 s++;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
394 tag.data2 = strtol(s, &s, 10);
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
395 if (*s != '}')
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
396 break;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
397 tag.key = 'o';
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
398 break;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
399
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
400 default: /* Unknown tag, we consider it's text */
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
401 break;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
402 }
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
403
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
404 if (tag.key == 0)
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
405 return start;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
406
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
407 microdvd_set_tag(tags, tag);
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
408 s++;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
409 }
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
410 return s;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
411 }
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
412
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
413 static void microdvd_open_tags(struct line *new_line, struct microdvd_tag *tags)
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
414 {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
415 int i, sidx;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
416 for (i = 0; i < sizeof(MICRODVD_TAGS) - 1; i++) {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
417 if (tags[i].persistent == MICRODVD_PERSISTENT_OPENED)
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
418 continue;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
419 switch (tags[i].key) {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
420 case 'Y':
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
421 case 'y':
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
422 for (sidx = 0; sidx < sizeof(MICRODVD_STYLES) - 1; sidx++)
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
423 if (tags[i].data1 & (1 << sidx))
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
424 append_text(new_line, "{\\%c1}", MICRODVD_STYLES[sidx]);
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
425 break;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
426
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
427 case 'c':
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
428 append_text(new_line, "{\\c&H%06X&}", tags[i].data1);
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
429 break;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
430
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
431 case 'f':
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
432 append_text(new_line, "{\\fn%.*s}", BSTR_P(tags[i].data_string));
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
433 break;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
434
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
435 case 's':
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
436 append_text(new_line, "{\\fs%d}", tags[i].data1);
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
437 break;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
438
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
439 case 'p':
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
440 if (tags[i].data1 == 0)
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
441 append_text(new_line, "{\\an8}");
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
442 break;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
443
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
444 case 'o':
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
445 append_text(new_line, "{\\pos(%d,%d)}",
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
446 tags[i].data1, tags[i].data2);
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
447 break;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
448 }
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
449 if (tags[i].persistent == MICRODVD_PERSISTENT_ON)
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
450 tags[i].persistent = MICRODVD_PERSISTENT_OPENED;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
451 }
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
452 }
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
453
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
454 static void microdvd_close_no_persistent_tags(struct line *new_line,
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
455 struct microdvd_tag *tags)
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
456 {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
457 int i, sidx;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
458
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
459 for (i = sizeof(MICRODVD_TAGS) - 2; i; i--) {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
460 if (tags[i].persistent != MICRODVD_PERSISTENT_OFF)
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
461 continue;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
462 switch (tags[i].key) {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
463
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
464 case 'y':
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
465 for (sidx = sizeof(MICRODVD_STYLES) - 2; sidx >= 0; sidx--)
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
466 if (tags[i].data1 & (1 << sidx))
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
467 append_text(new_line, "{\\%c0}", MICRODVD_STYLES[sidx]);
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
468 break;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
469
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
470 case 'c':
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
471 append_text(new_line, "{\\c}");
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
472 break;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
473
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
474 case 'f':
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
475 append_text(new_line, "{\\fn}");
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
476 break;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
477
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
478 case 's':
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
479 append_text(new_line, "{\\fs}");
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
480 break;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
481 }
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
482 tags[i].key = 0;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
483 }
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
484 }
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
485
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
486 /**
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
487 * \brief Convert MicroDVD lines into ASS markup
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
488 * \param orig original MicroDVD line. The content will remain untouched.
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
489 * \param dest ASS markup destination buffer.
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
490 * \param dest_buffer_size maximum size for the destination buffer.
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
491 */
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
492 void subassconvert_microdvd(const char *orig, char *dest, size_t dest_buffer_size)
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
493 {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
494 /* line is not const to avoid warnings with strtol, etc.
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
495 * orig content won't be changed */
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
496 char *line = (char *)orig;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
497 struct line new_line = {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
498 .buf = dest,
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
499 .bufsize = dest_buffer_size,
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
500 };
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
501 struct microdvd_tag tags[sizeof(MICRODVD_TAGS) - 1] = {};
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
502
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
503 while (*line) {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
504 line = microdvd_load_tags(tags, line);
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
505 microdvd_open_tags(&new_line, tags);
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
506
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
507 while (*line && *line != '|')
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
508 new_line.buf[new_line.len++] = *line++;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
509
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
510 if (*line == '|') {
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
511 microdvd_close_no_persistent_tags(&new_line, tags);
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
512 append_text(&new_line, "\\N");
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
513 line++;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
514 }
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
515 }
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
516 new_line.buf[new_line.len] = 0;
6e7c20b56c89 Move subassconvert.[ch] to the sub directory.
cigaes
parents:
diff changeset
517 }