diff options
| author | Carl Hetherington <cth@carlh.net> | 2014-02-26 17:48:29 +0000 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2014-02-26 17:48:29 +0000 |
| commit | 471c9d05fc19484f3e50cf805d14237b72bbb7b2 (patch) | |
| tree | 579ff1520617941734365a8e9f53985a86396507 /src | |
| parent | d7d879c988d484cb1a5fd65831001f656605c34e (diff) | |
Hacks to support MXF-wrapped subtitles.
Diffstat (limited to 'src')
| -rw-r--r-- | src/parse/subtitle.cc | 22 | ||||
| -rw-r--r-- | src/parse/subtitle.h | 2 | ||||
| -rw-r--r-- | src/subtitle_asset.cc | 79 | ||||
| -rw-r--r-- | src/subtitle_asset.h | 4 |
4 files changed, 93 insertions, 14 deletions
diff --git a/src/parse/subtitle.cc b/src/parse/subtitle.cc index 612af716..914be677 100644 --- a/src/parse/subtitle.cc +++ b/src/parse/subtitle.cc @@ -84,10 +84,14 @@ Font::Font (list<shared_ptr<Font> > const & font_nodes) LoadFont::LoadFont (shared_ptr<const cxml::Node> node) { - id = node->string_attribute ("Id"); - uri = node->string_attribute ("URI"); + optional<string> x = node->optional_string_attribute ("Id"); + if (!x) { + x = node->optional_string_attribute ("ID"); + } + id = x.get_value_or (""); + + uri = node->optional_string_attribute ("URI"); } - Subtitle::Subtitle (shared_ptr<const cxml::Node> node) { @@ -123,9 +127,19 @@ Subtitle::fade_time (shared_ptr<const cxml::Node> node, string name) Text::Text (shared_ptr<const cxml::Node> node) : v_align (CENTER) { + /* Vertical position */ text = node->content (); - v_position = node->number_attribute<float> ("VPosition"); + optional<float> x = node->optional_number_attribute<float> ("VPosition"); + if (!x) { + x = node->number_attribute<float> ("Vposition"); + } + v_position = x.get (); + + /* Vertical alignment */ optional<string> v = node->optional_string_attribute ("VAlign"); + if (!v) { + v = node->optional_string_attribute ("Valign"); + } if (v) { v_align = string_to_valign (v.get ()); } diff --git a/src/parse/subtitle.h b/src/parse/subtitle.h index c20278a3..3d99d9bc 100644 --- a/src/parse/subtitle.h +++ b/src/parse/subtitle.h @@ -92,7 +92,7 @@ public: LoadFont (boost::shared_ptr<const cxml::Node> node); std::string id; - std::string uri; + boost::optional<std::string> uri; }; } diff --git a/src/subtitle_asset.cc b/src/subtitle_asset.cc index a48a614d..4eb1a9cd 100644 --- a/src/subtitle_asset.cc +++ b/src/subtitle_asset.cc @@ -18,9 +18,12 @@ */ #include <fstream> +#include <cerrno> #include <boost/lexical_cast.hpp> #include <boost/algorithm/string.hpp> #include <libxml++/nodes/element.h> +#include "AS_DCP.h" +#include "KM_util.h" #include "subtitle_asset.h" #include "parse/subtitle.h" #include "util.h" @@ -31,16 +34,34 @@ using std::list; using std::ostream; using std::ofstream; using std::stringstream; +using std::cout; using boost::shared_ptr; using boost::lexical_cast; using boost::optional; using namespace libdcp; -SubtitleAsset::SubtitleAsset (string directory, string xml_file) - : Asset (directory, xml_file) +SubtitleAsset::SubtitleAsset (string directory, string file) + : Asset (directory, file) , _need_sort (false) { - read_xml (path().string()); + /* Grotesque hack: we should look in the PKL to see what type this file is; + instead we'll look at the first character to decide what to do. + I think this is easily fixable (properly) in 1.0. + */ + + FILE* f = fopen_boost (path(), "r"); + if (!f) { + throw FileError ("Could not open file for reading", file, errno); + } + unsigned char test[1]; + fread (test, 1, 1, f); + fclose (f); + + if (test[0] == '<' || test[0] == 0xef) { + read_xml (path().string()); + } else { + read_mxf (path().string()); + } } SubtitleAsset::SubtitleAsset (string directory, string movie_title, string language) @@ -54,13 +75,45 @@ SubtitleAsset::SubtitleAsset (string directory, string movie_title, string langu } void +SubtitleAsset::read_mxf (string mxf_file) +{ + ASDCP::TimedText::MXFReader reader; + Kumu::Result_t r = reader.OpenRead (mxf_file.c_str ()); + if (ASDCP_FAILURE (r)) { + boost::throw_exception (MXFFileError ("could not open MXF file for reading", mxf_file, r)); + } + + string s; + reader.ReadTimedTextResource (s, 0, 0); + shared_ptr<cxml::Document> xml (new cxml::Document ("SubtitleReel")); + stringstream t; + t << s; + xml->read_stream (t); + read_xml (xml); +} + +void SubtitleAsset::read_xml (string xml_file) { shared_ptr<cxml::Document> xml (new cxml::Document ("DCSubtitle")); xml->read_file (xml_file); + read_xml (xml); +} + +void +SubtitleAsset::read_xml (shared_ptr<cxml::Document> xml) +{ + /* XXX: hacks aplenty in here; need separate parsers for DCSubtitle and SubtitleReel */ - _uuid = xml->string_child ("SubtitleID"); - _movie_title = xml->string_child ("MovieTitle"); + /* DCSubtitle */ + optional<string> x = xml->optional_string_child ("SubtitleID"); + if (!x) { + /* SubtitleReel */ + x = xml->optional_string_child ("Id"); + } + _uuid = x.get_value_or (""); + + _movie_title = xml->optional_string_child ("MovieTitle"); _reel_number = xml->string_child ("ReelNumber"); _language = xml->string_child ("Language"); @@ -73,6 +126,12 @@ SubtitleAsset::read_xml (string xml_file) in a sane way. */ + shared_ptr<cxml::Node> subtitle_list = xml->optional_node_child ("SubtitleList"); + if (subtitle_list) { + list<shared_ptr<libdcp::parse::Font> > font = type_children<libdcp::parse::Font> (subtitle_list, "Font"); + copy (font.begin(), font.end(), back_inserter (font_nodes)); + } + ParseState parse_state; examine_font_nodes (xml, font_nodes, parse_state); } @@ -182,7 +241,7 @@ SubtitleAsset::font_id_to_name (string id) const return ""; } - if ((*i)->uri == "arial.ttf") { + if ((*i)->uri && (*i)->uri.get() == "arial.ttf") { return "Arial"; } @@ -316,7 +375,9 @@ SubtitleAsset::xml_as_string () const root->set_attribute ("Version", "1.0"); root->add_child("SubtitleID")->add_child_text (_uuid); - root->add_child("MovieTitle")->add_child_text (_movie_title); + if (_movie_title) { + root->add_child("MovieTitle")->add_child_text (_movie_title.get ()); + } root->add_child("ReelNumber")->add_child_text (lexical_cast<string> (_reel_number)); root->add_child("Language")->add_child_text (_language); @@ -327,7 +388,9 @@ SubtitleAsset::xml_as_string () const if (!_load_font_nodes.empty ()) { xmlpp::Element* load_font = root->add_child("LoadFont"); load_font->set_attribute("Id", _load_font_nodes.front()->id); - load_font->set_attribute("URI", _load_font_nodes.front()->uri); + if (_load_font_nodes.front()->uri) { + load_font->set_attribute("URI", _load_font_nodes.front()->uri.get ()); + } } list<shared_ptr<Subtitle> > sorted = _subtitles; diff --git a/src/subtitle_asset.h b/src/subtitle_asset.h index 0598a296..a7ec641c 100644 --- a/src/subtitle_asset.h +++ b/src/subtitle_asset.h @@ -169,6 +169,8 @@ protected: private: std::string font_id_to_name (std::string id) const; + void read_mxf (std::string); + void read_xml (boost::shared_ptr<cxml::Document>); struct ParseState { std::list<boost::shared_ptr<parse::Font> > font_nodes; @@ -190,7 +192,7 @@ private: ParseState& parse_state ); - std::string _movie_title; + boost::optional<std::string> _movie_title; /* strangely, this is sometimes a string */ std::string _reel_number; std::string _language; |
