From 4c84e14b9e6566e176e702f79e6e0bd66a62d33e Mon Sep 17 00:00:00 2001 From: Moritz Bunkus Date: Thu, 19 Apr 2007 07:50:15 +0000 Subject: [PATCH] Allow negative timecodes in "delay:" lines in VobSub subtitles. Fix for bug 241. --- ChangeLog | 5 +++++ src/common/common.cpp | 23 +++++++++++++++++------ src/common/common.h | 3 ++- src/input/r_vobsub.cpp | 2 +- 4 files changed, 25 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3a53a1b27..f7ab6ab82 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2007-04-19 Moritz Bunkus + + * mkvmerge: bug fix: Fixed the VobSub reader so that "delay:" + lines with negative timecodes are accepted. Fix for bug 241. + 2007-04-18 Moritz Bunkus * mkvmerge: bug fix: Improved the file type detection code for diff --git a/src/common/common.cpp b/src/common/common.cpp index 8bfe79f06..915847104 100644 --- a/src/common/common.cpp +++ b/src/common/common.cpp @@ -1611,7 +1611,8 @@ set_tcp_error(const string &error) { bool parse_timecode(const string &src, - int64_t &timecode) { + int64_t &timecode, + bool allow_negative) { // Recognized format: // 1. XXXXXXXu with XXXXXX being a number followed // by one of the units 's', 'ms', 'us' or 'ns' @@ -1620,13 +1621,21 @@ parse_timecode(const string &src, // 2. HH:MM:SS:nnnnnnnnn with up to nine digits 'n' for ns precision; // HH: is optional; HH, MM and SS can be either one or two digits. int h, m, s, n, i, values[4], num_values, num_digits, num_colons; + int offset = 0, negative = 1; bool decimal_point_found; if (src.empty()) return false; + if ('-' == src[0]) { + if (!allow_negative) + return false; + negative = -1; + offset = 1; + } + try { - if (src.length() < 2) + if (src.length() < (2 + offset)) throw false; string unit = src.substr(src.length() - 2, 2); @@ -1646,13 +1655,13 @@ parse_timecode(const string &src, else throw false; - if (src.length() < (unit_length + 1)) + if (src.length() < (unit_length + 1 + offset)) throw false; - if (!parse_int(src.substr(0, src.length() - unit_length), value)) + if (!parse_int(src.substr(offset, src.length() - unit_length - offset), value)) throw false; - timecode = value * multiplier; + timecode = value * multiplier * negative; return true; } catch (...) { @@ -1664,7 +1673,7 @@ parse_timecode(const string &src, decimal_point_found = false; memset(&values, 0, sizeof(int) * 4); - for (i = 0; src.length() > i; ++i) { + for (i = offset; src.length() > i; ++i) { if (isdigit(src[i])) { if (decimal_point_found && (9 == num_digits)) return set_tcp_error("Invalid format: More than nine nano-second " @@ -1749,6 +1758,8 @@ parse_timecode(const string &src, timecode = ((int64_t)h * 60 * 60 + (int64_t)m * 60 + (int64_t)s) * 1000000000ll + n; + timecode *= negative; + timecode_parser_error = "no error"; return true; } diff --git a/src/common/common.h b/src/common/common.h index 0ddb55717..fed3ae1fd 100644 --- a/src/common/common.h +++ b/src/common/common.h @@ -97,7 +97,8 @@ using namespace std; (int32_t)((t) % 1000000000) #define ARG_TIMECODEN(t) ARG_TIMECODENINT((int64_t)(t)) extern string MTX_DLL_API timecode_parser_error; -extern bool MTX_DLL_API parse_timecode(const string &s, int64_t &timecode); +extern bool MTX_DLL_API parse_timecode(const string &s, int64_t &timecode, + bool allow_negative = false); extern bool MTX_DLL_API suppress_warnings; void MTX_DLL_API fix_format(const char *fmt, string &new_fmt); diff --git a/src/input/r_vobsub.cpp b/src/input/r_vobsub.cpp index f7fc3c524..ca9a9e7ee 100644 --- a/src/input/r_vobsub.cpp +++ b/src/input/r_vobsub.cpp @@ -248,7 +248,7 @@ vobsub_reader_c::parse_headers() { line.erase(0, 6); strip(line); - if (!parse_timecode(line, timestamp)) + if (!parse_timecode(line, timestamp, true)) mxerror(PFX "'%s', line " LLD ": The 'delay' timestamp could not be " "parsed.\n", ti.fname.c_str(), line_no); delay = timestamp;