52 .offset = offsetof(
ASS, script_info),
61 { .section =
"V4+ Styles",
62 .format_header =
"Format",
63 .fields_header =
"Style",
66 .offset_count = offsetof(
ASS, styles_count),
79 { .section =
"V4 Styles",
80 .format_header =
"Format",
81 .fields_header =
"Style",
84 .offset_count = offsetof(
ASS, styles_count),
96 { .section =
"Events",
97 .format_header =
"Format",
98 .fields_header =
"Dialogue",
101 .offset_count = offsetof(
ASS, dialogs_count),
119 memcpy(str, buf, len);
123 *(
char **)dest = str;
129 return sscanf(buf,
"%d", (
int *)dest) == 1;
133 return sscanf(buf,
"%f", (
float *)dest) == 1;
137 return sscanf(buf,
"&H%8x", (
int *)dest) == 1 ||
138 sscanf(buf,
"%d", (
int *)dest) == 1;
143 if ((c = sscanf(buf,
"%d:%02d:%02d.%02d", &h, &m, &s, &cs)) == 4)
144 *(
int *)dest = 360000*h + 6000*m + 100*s + cs;
150 if (sscanf(buf,
"%d", &a) == 1) {
152 *(
int *)dest = a + ((a&4) >> 1) - 5*!!(a&8);
185 tmp += *count * section->
size;
186 memset(tmp, 0, section->
size);
193 return buf ==
'\r' || buf ==
'\n' || buf == 0;
210 while (buf && *buf) {
215 if (buf[0] ==
';' || (buf[0] ==
'!' && buf[1] ==
':')) {
219 if (strncmp(buf, section->
format_header, len) || buf[len] !=
':')
224 len = strcspn(buf,
", \r\n");
225 if (!(tmp =
av_realloc(order, (*number + 1) *
sizeof(*order))))
230 if (!strncmp(buf, section->
fields[i].
name, len)) {
235 buf =
skip_space(buf + len + (buf[len] ==
','));
240 if (!strncmp(buf, section->
fields_header, len) && buf[len] ==
':') {
242 if (!struct_ptr)
return NULL;
244 for (i=0; !
is_eol(*buf) && i < *number; i++) {
245 int last = i == *number - 1;
247 len = strcspn(buf, last ?
"\r\n" :
",\r\n");
257 len = strcspn(buf,
":\r\n");
258 if (buf[len] ==
':') {
260 if (!strncmp(buf, section->
fields[i].
name, len)) {
270 buf += strcspn(buf,
"\n");
284 while (buf && *buf) {
285 if (sscanf(buf,
"[%15[0-9A-Za-z+ ]]%c", section, &c) == 2) {
286 buf += strcspn(buf,
"\n") + 1;
288 if (!strcmp(section, ass_sections[i].section)) {
293 buf += strcspn(buf,
"\n") + 1;
312 int i, j, *count,
c = 1;
321 for (i=0; i<*count; i++, ptr += section->
size)
334 int cache,
int *number)
340 if (!strcmp(ass_sections[i].
section,
"Events")) {
368 const char *text =
NULL;
372 while (buf && *buf) {
373 if (text && callbacks->
text &&
374 (sscanf(buf,
"\\%1[nN]", new_line) == 1 ||
375 !strncmp(buf,
"{\\", 2))) {
376 callbacks->
text(priv, text, text_len);
379 if (sscanf(buf,
"\\%1[nN]", new_line) == 1) {
381 callbacks->
new_line(priv, new_line[0] ==
'N');
383 }
else if (!strncmp(buf,
"{\\", 2)) {
385 while (*buf ==
'\\') {
386 char style[2],
c[2], sep[2], c_num[2] =
"0", tmp[128] = {0};
387 unsigned int color = 0xFFFFFFFF;
388 int len,
size = -1, an = -1, alpha = -1;
389 int x1, y1, x2, y2,
t1 = -1,
t2 = -1;
390 if (sscanf(buf,
"\\%1[bisu]%1[01\\}]%n", style, c, &len) > 1) {
391 int close = c[0] ==
'0' ? 1 : c[0] ==
'1' ? 0 : -1;
393 if (callbacks->
style)
394 callbacks->
style(priv, style[0], close);
395 }
else if (sscanf(buf,
"\\c%1[\\}]%n", sep, &len) > 0 ||
396 sscanf(buf,
"\\c&H%X&%1[\\}]%n", &color, sep, &len) > 1 ||
397 sscanf(buf,
"\\%1[1234]c%1[\\}]%n", c_num, sep, &len) > 1 ||
398 sscanf(buf,
"\\%1[1234]c&H%X&%1[\\}]%n", c_num, &color, sep, &len) > 2) {
399 if (callbacks->
color)
400 callbacks->
color(priv, color, c_num[0] -
'0');
401 }
else if (sscanf(buf,
"\\alpha%1[\\}]%n", sep, &len) > 0 ||
402 sscanf(buf,
"\\alpha&H%2X&%1[\\}]%n", &alpha, sep, &len) > 1 ||
403 sscanf(buf,
"\\%1[1234]a%1[\\}]%n", c_num, sep, &len) > 1 ||
404 sscanf(buf,
"\\%1[1234]a&H%2X&%1[\\}]%n", c_num, &alpha, sep, &len) > 2) {
405 if (callbacks->
alpha)
406 callbacks->
alpha(priv, alpha, c_num[0] -
'0');
407 }
else if (sscanf(buf,
"\\fn%1[\\}]%n", sep, &len) > 0 ||
408 sscanf(buf,
"\\fn%127[^\\}]%1[\\}]%n", tmp, sep, &len) > 1) {
411 }
else if (sscanf(buf,
"\\fs%1[\\}]%n", sep, &len) > 0 ||
412 sscanf(buf,
"\\fs%u%1[\\}]%n", &size, sep, &len) > 1) {
415 }
else if (sscanf(buf,
"\\a%1[\\}]%n", sep, &len) > 0 ||
416 sscanf(buf,
"\\a%2u%1[\\}]%n", &an, sep, &len) > 1 ||
417 sscanf(buf,
"\\an%1[\\}]%n", sep, &len) > 0 ||
418 sscanf(buf,
"\\an%1u%1[\\}]%n", &an, sep, &len) > 1) {
419 if (an != -1 && buf[2] !=
'n')
420 an = (an&3) + (an&4 ? 6 : an&8 ? 3 : 0);
423 }
else if (sscanf(buf,
"\\r%1[\\}]%n", sep, &len) > 0 ||
424 sscanf(buf,
"\\r%127[^\\}]%1[\\}]%n", tmp, sep, &len) > 1) {
427 }
else if (sscanf(buf,
"\\move(%d,%d,%d,%d)%1[\\}]%n", &x1, &y1, &x2, &y2, sep, &len) > 4 ||
428 sscanf(buf,
"\\move(%d,%d,%d,%d,%d,%d)%1[\\}]%n", &x1, &y1, &x2, &y2, &t1, &
t2, sep, &len) > 6) {
430 callbacks->
move(priv, x1, y1, x2, y2, t1,
t2);
431 }
else if (sscanf(buf,
"\\pos(%d,%d)%1[\\}]%n", &x1, &y1, sep, &len) > 2) {
433 callbacks->
move(priv, x1, y1, x1, y1, -1, -1);
434 }
else if (sscanf(buf,
"\\org(%d,%d)%1[\\}]%n", &x1, &y1, sep, &len) > 2) {
436 callbacks->
origin(priv, x1, y1);
438 len = strcspn(buf+1,
"\\}") + 2;
453 if (text && callbacks->
text)
454 callbacks->
text(priv, text, text_len);
456 callbacks->
end(priv);
465 if (!style || !*style)