X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Fdcp_reader.cc;h=0c7a29a90aaa9d564f3f18932c00e305599fbd55;hb=08fa1aa2bc718635c3ae0f991800c6c6cfd62a2b;hp=9727ef8cc9548589b759bb7a95e2695c83dc9f6e;hpb=0d022c11fd502186caef368d9cd77e095f74026c;p=libsub.git diff --git a/src/dcp_reader.cc b/src/dcp_reader.cc index 9727ef8..0c7a29a 100644 --- a/src/dcp_reader.cc +++ b/src/dcp_reader.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2014-2015 Carl Hetherington + Copyright (C) 2014-2021 Carl Hetherington This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -18,97 +18,120 @@ */ #include "dcp_reader.h" -#include "vertical_reference.h" -#include "xml.h" -#include "util.h" -#include "dcp/font.h" -#include "dcp/text.h" -#include "dcp/subtitle.h" -#include -#include -#include - -using std::list; -using std::cout; +#include "compose.hpp" +#include "exceptions.h" +#include +#include +#include +#include + +using std::dynamic_pointer_cast; +using std::exception; +using std::make_shared; +using std::shared_ptr; using std::string; -using boost::shared_ptr; using boost::optional; using namespace sub; -void -DCPReader::parse_common (cxml::NodePtr root, optional tcr) +static Time +dcp_to_sub_time (dcp::Time t) { - _reel_number = root->string_child ("ReelNumber"); - _language = root->string_child ("Language"); + return Time::from_hms (t.h, t.m, t.s, t.e * 1000.0 / t.tcr); +} - ParseState parse_state; - parse_node (root->node(), parse_state, tcr); +static Colour +dcp_to_sub_colour (dcp::Colour c) +{ + return Colour (c.r / 255.0, c.g / 255.0, c.b / 255.0); } -void -DCPReader::parse_node (xmlpp::Node const * node, ParseState& parse_state, optional tcr) +DCPReader::DCPReader (boost::filesystem::path file) { - xmlpp::Node::NodeList children = node->get_children (); - for (xmlpp::Node::NodeList::iterator i = children.begin(); i != children.end(); ++i) { - xmlpp::ContentNode const * c = dynamic_cast (*i); - if (c) { - maybe_add_subtitle (c->get_content (), parse_state); - } + shared_ptr sc; + string interop_error; + string smpte_error; + + try { + sc = make_shared(file); + } catch (exception& e) { + interop_error = e.what (); + } - xmlpp::Element* e = dynamic_cast (*i); - if (e) { - cxml::NodePtr n (new cxml::Node (e)); - if (n->name() == "Font") { - parse_state.font_nodes.push_back (shared_ptr (new dcp::Font (n))); - parse_node (e, parse_state, tcr); - parse_state.font_nodes.pop_back (); - } else if (n->name() == "Text") { - parse_state.text_nodes.push_back (shared_ptr (new dcp::Text (n))); - parse_node (e, parse_state, tcr); - parse_state.text_nodes.pop_back (); - } else if (n->name() == "Subtitle") { - parse_state.subtitle_nodes.push_back (shared_ptr (new dcp::Subtitle (n, tcr))); - parse_node (e, parse_state, tcr); - parse_state.subtitle_nodes.pop_back (); - } else if (n->name() == "SubtitleList") { - parse_node (e, parse_state, tcr); - } + if (!sc) { + try { + sc = make_shared(file); + } catch (exception& e) { + smpte_error = e.what(); } } -} -void -DCPReader::maybe_add_subtitle (string text, ParseState const & parse_state) -{ - if (empty_or_white_space (text)) { - return; + if (!sc) { + throw DCPError(String::compose("Could not read subtitles (%1 / %2)", interop_error, smpte_error)); } - if (parse_state.text_nodes.empty() || parse_state.subtitle_nodes.empty ()) { - return; - } - dcp::Font effective_font (parse_state.font_nodes); - dcp::Text effective_text (*parse_state.text_nodes.back ()); - dcp::Subtitle effective_subtitle (*parse_state.subtitle_nodes.back ()); - - RawSubtitle rs; - - rs.text = text; - rs.font = effective_font.id; - rs.font_size.set_proportional (float (effective_font.size) / (72 * 11)); - rs.effect = effective_font.effect; - rs.effect_colour = effective_font.effect_colour; - rs.colour = effective_font.colour.get(); - rs.bold = false; - rs.italic = effective_font.italic.get(); - rs.underline = false; - rs.vertical_position.proportional = float (effective_text.v_position) / 100; - rs.vertical_position.reference = effective_text.v_align; - rs.from = effective_subtitle.in; - rs.to = effective_subtitle.out; - rs.fade_up = effective_subtitle.fade_up_time; - rs.fade_down = effective_subtitle.fade_down_time; - - _subs.push_back (rs); + for (auto i: sc->subtitles()) { + + /* We don't deal with image subs */ + auto is = dynamic_pointer_cast(i); + if (!is) { + continue; + } + + RawSubtitle rs; + rs.text = is->text (); + rs.font = is->font (); + rs.font_size = FontSize::from_proportional (is->size() / (72.0 * 11.0)); + + switch (is->effect ()) { + case dcp::Effect::BORDER: + rs.effect = BORDER; + break; + case dcp::Effect::SHADOW: + rs.effect = SHADOW; + break; + default: + break; + } + + rs.effect_colour = dcp_to_sub_colour (is->effect_colour()); + + rs.colour = dcp_to_sub_colour (is->colour()); + rs.bold = is->bold (); + rs.italic = is->italic (); + rs.underline = is->underline (); + + switch (is->h_align()) { + case dcp::HAlign::LEFT: + rs.horizontal_position.reference = LEFT_OF_SCREEN; + break; + case dcp::HAlign::CENTER: + rs.horizontal_position.reference = HORIZONTAL_CENTRE_OF_SCREEN; + break; + case dcp::HAlign::RIGHT: + rs.horizontal_position.reference = RIGHT_OF_SCREEN; + break; + } + + rs.vertical_position.proportional = is->v_position(); + switch (is->v_align()) { + case dcp::VAlign::TOP: + rs.vertical_position.reference = TOP_OF_SCREEN; + break; + case dcp::VAlign::CENTER: + rs.vertical_position.reference = VERTICAL_CENTRE_OF_SCREEN; + break; + case dcp::VAlign::BOTTOM: + rs.vertical_position.reference = BOTTOM_OF_SCREEN; + break; + } + + rs.from = dcp_to_sub_time (is->in ()); + rs.to = dcp_to_sub_time (is->out ()); + + rs.fade_up = dcp_to_sub_time (is->fade_up_time ()); + rs.fade_down = dcp_to_sub_time (is->fade_down_time ()); + + _subs.push_back (rs); + } }