diff options
| author | Carl Hetherington <cth@carlh.net> | 2014-05-30 13:02:29 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2014-05-30 13:02:29 +0100 |
| commit | b365da4229b2a9d0ceef632af6880a38ecb65325 (patch) | |
| tree | b37f7c5d68206c6aab456ec44ac666c7f4b6bdf2 /src | |
| parent | 38a5ff713757b9dc0cb67cb09613182c46dc9657 (diff) | |
Various fixes to STL read/write.
Diffstat (limited to 'src')
| -rw-r--r-- | src/stl_binary_reader.cc | 48 | ||||
| -rw-r--r-- | src/stl_binary_tables.cc | 20 | ||||
| -rw-r--r-- | src/stl_binary_tables.h | 3 | ||||
| -rw-r--r-- | src/stl_binary_writer.cc | 87 | ||||
| -rw-r--r-- | src/time_pair.cc | 13 | ||||
| -rw-r--r-- | src/time_pair.h | 2 |
6 files changed, 158 insertions, 15 deletions
diff --git a/src/stl_binary_reader.cc b/src/stl_binary_reader.cc index 6c02526..d0fc266 100644 --- a/src/stl_binary_reader.cc +++ b/src/stl_binary_reader.cc @@ -108,17 +108,49 @@ STLBinaryReader::STLBinaryReader (istream& in) sub.from.set_frame (get_timecode (5)); sub.to.set_frame (get_timecode (9)); sub.vertical_position.line = get_int (13, 1) + i; - - /* XXX: justification, effects */ - /* 8Fh is unused space, so trim the string to the first instance of that */ - size_t unused = lines[i].find_first_of ('\x8f'); - if (unused != string::npos) { - lines[i] = lines[i].substr (0, unused); + string text; + for (size_t j = 0; j < lines[i].size(); ++j) { + + unsigned char const c = static_cast<unsigned char> (lines[i][j]); + + if (c == 0x8f) { + /* Unused space i.e. end of line */ + break; + } + + if (c >= 0x80 && c <= 0x83) { + /* Italic or underline control code */ + sub.text = utf_to_utf<char> (iso6937_to_utf16 (text.c_str())); + _subs.push_back (sub); + text.clear (); + } + + switch (c) { + case 0x80: + sub.italic = true; + break; + case 0x81: + sub.italic = false; + break; + case 0x82: + sub.underline = true; + break; + case 0x83: + sub.underline = false; + break; + default: + text += lines[i][j]; + break; + } } - sub.text = utf_to_utf<char> (iso6937_to_utf16 (lines[i].c_str())); - _subs.push_back (sub); + if (!text.empty ()) { + sub.text = utf_to_utf<char> (iso6937_to_utf16 (text.c_str())); + _subs.push_back (sub); + } + + /* XXX: justification */ } } } diff --git a/src/stl_binary_tables.cc b/src/stl_binary_tables.cc index 664921d..7fdad7b 100644 --- a/src/stl_binary_tables.cc +++ b/src/stl_binary_tables.cc @@ -121,6 +121,24 @@ STLBinaryTables::language_enum_to_file (Language e) const return enum_to_file (e, _language_map); } +int +STLBinaryTables::cumulative_status_enum_to_file (CumulativeStatus v) const +{ + return enum_to_file (v, _cumulative_status_map); +} + +int +STLBinaryTables::justification_enum_to_file (Justification v) const +{ + return enum_to_file (v, _justification_map); +} + +int +STLBinaryTables::comment_enum_to_file (Comment v) const +{ + return enum_to_file (v, _comment_map); +} + string STLBinaryTables::display_standard_enum_to_description (DisplayStandard v) const { @@ -162,7 +180,7 @@ STLBinaryTables::comment_enum_to_description (Comment v) const { return enum_to_description (v, _comment_map); } - + STLBinaryTables::STLBinaryTables () { code<DisplayStandard, string> (_display_standard_map, " ", DISPLAY_STANDARD_UNDEFINED, "Undefined"); diff --git a/src/stl_binary_tables.h b/src/stl_binary_tables.h index 0a85dd8..3118b02 100644 --- a/src/stl_binary_tables.h +++ b/src/stl_binary_tables.h @@ -198,6 +198,9 @@ public: Comment comment_file_to_enum (int) const; std::string language_enum_to_file (Language) const; + int cumulative_status_enum_to_file (CumulativeStatus) const; + int justification_enum_to_file (Justification) const; + int comment_enum_to_file (Comment) const; std::string display_standard_enum_to_description (DisplayStandard) const; std::string language_group_enum_to_description (LanguageGroup) const; diff --git a/src/stl_binary_writer.cc b/src/stl_binary_writer.cc index e662764..334a5bb 100644 --- a/src/stl_binary_writer.cc +++ b/src/stl_binary_writer.cc @@ -33,6 +33,7 @@ using std::string; using std::setw; using std::setfill; using std::max; +using std::cout; using namespace sub; static void @@ -51,7 +52,7 @@ put_string (char* p, unsigned int n, string s) } static void -put_int (char* p, int v, unsigned int n) +put_int_as_string (char* p, int v, unsigned int n) { std::stringstream s; /* Be careful to ensure we get no thousands separators */ @@ -62,6 +63,14 @@ put_int (char* p, int v, unsigned int n) put_string (p, s.str ()); } +static void +put_int_as_int (char* p, int v, unsigned int n) +{ + for (unsigned int i = 0; i < n; ++i) { + *p++ = (v & ((1 << ((i + 1) * 8)) - 1)) >> (i * 8); + } +} + /** @param language ISO 3-character country code for the language of the subtitles */ void sub::write_stl_binary ( @@ -158,17 +167,17 @@ sub::write_stl_binary ( put_string (buffer + 208, "0000000000000000"); put_string (buffer + 224, creation_date); put_string (buffer + 230, revision_date); - put_int (buffer + 236, revision_number, 2); + put_int_as_string (buffer + 236, revision_number, 2); /* TTI blocks */ - put_int (buffer + 238, subtitles.size (), 5); + put_int_as_string (buffer + 238, subtitles.size (), 5); /* Total number of subtitles */ - put_int (buffer + 243, subtitles.size (), 5); + put_int_as_string (buffer + 243, subtitles.size (), 5); /* Total number of subtitle groups */ put_string (buffer + 248, "000"); /* Maximum number of displayable characters in any text row */ - put_int (buffer + 251, 2, longest); + put_int_as_string (buffer + 251, 2, longest); /* Maximum number of displayable rows */ - put_int (buffer + 253, 2, rows); + put_int_as_string (buffer + 253, 2, rows); /* Time code status */ put_string (buffer + 255, "1"); /* Start-of-programme time code */ @@ -186,8 +195,74 @@ sub::write_stl_binary ( output.write (buffer, 1024); + int N = 0; for (list<Subtitle>::const_iterator i = subtitles.begin(); i != subtitles.end(); ++i) { + + /* Subtitle group number */ + put_int_as_int (buffer + 0, 0, 1); + /* Subtitle number */ + put_int_as_int (buffer + 1, N, 2); + /* Extension block number */ + put_int_as_int (buffer + 3, 0, 1); + /* Cumulative status */ + put_int_as_int (buffer + 4, tables.cumulative_status_enum_to_file (CUMULATIVE_STATUS_NOT_CUMULATIVE), 1); + /* Time code in */ + put_int_as_int (buffer + 5, i->from.frame(frames_per_second).hours (), 1); + put_int_as_int (buffer + 6, i->from.frame(frames_per_second).minutes (), 1); + put_int_as_int (buffer + 7, i->from.frame(frames_per_second).seconds (), 1); + put_int_as_int (buffer + 8, i->from.frame(frames_per_second).frames (), 1); + /* Time code out */ + put_int_as_int (buffer + 9, i->to.frame(frames_per_second).hours (), 1); + put_int_as_int (buffer + 10, i->to.frame(frames_per_second).minutes (), 1); + put_int_as_int (buffer + 11, i->to.frame(frames_per_second).seconds (), 1); + put_int_as_int (buffer + 12, i->to.frame(frames_per_second).frames (), 1); + /* Vertical position */ + /* XXX */ + put_int_as_int (buffer + 13, 0, 1); + /* Justification code */ + /* XXX */ + put_int_as_int (buffer + 14, tables.justification_enum_to_file (JUSTIFICATION_NONE), 1); + /* Comment flag */ + put_int_as_int (buffer + 15, tables.comment_enum_to_file (COMMENT_NO), 1); + + /* Text */ + string text; + bool italic = false; + bool underline = false; + for (list<Line>::const_iterator j = i->lines.begin(); j != i->lines.end(); ++j) { + for (list<Block>::const_iterator k = j->blocks.begin(); k != j->blocks.end(); ++k) { + if (k->underline && !underline) { + text += "\x82"; + underline = true; + } else if (underline && !k->underline) { + text += "\x83"; + underline = false; + } + if (k->italic && !italic) { + text += "\x80"; + italic = true; + } else if (italic && !k->italic) { + text += "\x81"; + italic = false; + } + + text += k->text; + } + + text += "\x8A"; + } + + if (text.length() > 111) { + text = text.substr (111); + } + + while (text.length() < 112) { + text += "\x8F"; + } + + put_string (buffer + 16, text); + output.write (buffer, 128); } delete[] buffer; diff --git a/src/time_pair.cc b/src/time_pair.cc index 186d54c..3ef2429 100644 --- a/src/time_pair.cc +++ b/src/time_pair.cc @@ -19,6 +19,7 @@ #include "time_pair.h" +using std::ostream; using namespace sub; FrameTime @@ -54,3 +55,15 @@ TimePair::operator== (TimePair const & other) const return false; } + +ostream & +sub::operator<< (ostream& s, TimePair const & t) +{ + if (t.frame ()) { + s << "[FRAME] " << t.frame().get(); + } else { + s << "[METRIC]" << t.metric().get(); + } + + return s; +} diff --git a/src/time_pair.h b/src/time_pair.h index 404c143..9b9c357 100644 --- a/src/time_pair.h +++ b/src/time_pair.h @@ -57,6 +57,8 @@ private: boost::optional<MetricTime> _metric; }; +std::ostream& operator<< (std::ostream & s, TimePair const &); + } #endif |
