summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2014-05-30 13:02:29 +0100
committerCarl Hetherington <cth@carlh.net>2014-05-30 13:02:29 +0100
commitb365da4229b2a9d0ceef632af6880a38ecb65325 (patch)
treeb37f7c5d68206c6aab456ec44ac666c7f4b6bdf2 /src
parent38a5ff713757b9dc0cb67cb09613182c46dc9657 (diff)
Various fixes to STL read/write.
Diffstat (limited to 'src')
-rw-r--r--src/stl_binary_reader.cc48
-rw-r--r--src/stl_binary_tables.cc20
-rw-r--r--src/stl_binary_tables.h3
-rw-r--r--src/stl_binary_writer.cc87
-rw-r--r--src/time_pair.cc13
-rw-r--r--src/time_pair.h2
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