#include "mono_picture_mxf.h"
#include "stereo_picture_mxf.h"
#include "sound_mxf.h"
-#include "subtitle_content.h"
+#include "subtitle_asset.h"
#include "xyz_image.h"
#include "colour_conversion.h"
#include "rgb_xyz.h"
std::cout << "3D picture\n";
} else if (boost::dynamic_pointer_cast<dcp::SoundMXF> (*i)) {
std::cout << "Sound\n";
- } else if (boost::dynamic_pointer_cast<dcp::SubtitleContent> (*i)) {
+ } else if (boost::dynamic_pointer_cast<dcp::SubtitleAsset> (*i)) {
std::cout << "Subtitle\n";
} else if (boost::dynamic_pointer_cast<dcp::CPL> (*i)) {
std::cout << "CPL\n";
#include "dcp.h"
#include "sound_mxf.h"
#include "picture_mxf.h"
-#include "interop_subtitle_content.h"
-#include "smpte_subtitle_content.h"
+#include "interop_subtitle_asset.h"
+#include "smpte_subtitle_asset.h"
#include "mono_picture_mxf.h"
#include "stereo_picture_mxf.h"
#include "util.h"
if (root == "CompositionPlaylist") {
_assets.push_back (shared_ptr<CPL> (new CPL (path)));
} else if (root == "DCSubtitle") {
- _assets.push_back (shared_ptr<InteropSubtitleContent> (new InteropSubtitleContent (path)));
+ _assets.push_back (shared_ptr<InteropSubtitleAsset> (new InteropSubtitleAsset (path)));
}
} else if (boost::algorithm::ends_with (path.string(), ".mxf")) {
ASDCP::EssenceType_t type;
_assets.push_back (shared_ptr<StereoPictureMXF> (new StereoPictureMXF (path)));
break;
case ASDCP::ESS_TIMED_TEXT:
- _assets.push_back (shared_ptr<SMPTESubtitleContent> (new SMPTESubtitleContent (path)));
+ _assets.push_back (shared_ptr<SMPTESubtitleAsset> (new SMPTESubtitleAsset (path)));
break;
default:
throw DCPReadError ("Unknown MXF essence type");
--- /dev/null
+/*
+ Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
+
+ 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
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "interop_subtitle_asset.h"
+#include "interop_load_font_node.h"
+#include "xml.h"
+#include "raw_convert.h"
+#include "font_node.h"
+#include <libxml++/libxml++.h>
+#include <boost/foreach.hpp>
+#include <cmath>
+
+using std::list;
+using std::string;
+using std::cout;
+using boost::shared_ptr;
+using boost::optional;
+using boost::dynamic_pointer_cast;
+using namespace dcp;
+
+InteropSubtitleAsset::InteropSubtitleAsset (boost::filesystem::path file)
+ : SubtitleAsset (file)
+{
+ shared_ptr<cxml::Document> xml (new cxml::Document ("DCSubtitle"));
+ xml->read_file (file);
+ _id = xml->string_child ("SubtitleID");
+
+ _movie_title = xml->string_child ("MovieTitle");
+ _load_font_nodes = type_children<dcp::InteropLoadFontNode> (xml, "LoadFont");
+
+ list<cxml::NodePtr> f = xml->node_children ("Font");
+ list<shared_ptr<dcp::FontNode> > font_nodes;
+ BOOST_FOREACH (cxml::NodePtr& i, f) {
+ font_nodes.push_back (shared_ptr<FontNode> (new FontNode (i, 250)));
+ }
+
+ parse_common (xml, font_nodes);
+}
+
+InteropSubtitleAsset::InteropSubtitleAsset (string movie_title, string language)
+ : _movie_title (movie_title)
+{
+ _language = language;
+}
+
+struct SubtitleSorter {
+ bool operator() (SubtitleString const & a, SubtitleString const & b) {
+ if (a.in() != b.in()) {
+ return a.in() < b.in();
+ }
+ return a.v_position() < b.v_position();
+ }
+};
+
+Glib::ustring
+InteropSubtitleAsset::xml_as_string () const
+{
+ xmlpp::Document doc;
+ xmlpp::Element* root = doc.create_root_node ("DCSubtitle");
+ root->set_attribute ("Version", "1.0");
+
+ root->add_child("SubtitleID")->add_child_text (_id);
+ root->add_child("MovieTitle")->add_child_text (_movie_title);
+ root->add_child("ReelNumber")->add_child_text (raw_convert<string> (_reel_number));
+ root->add_child("Language")->add_child_text (_language);
+
+ for (list<shared_ptr<InteropLoadFontNode> >::const_iterator i = _load_font_nodes.begin(); i != _load_font_nodes.end(); ++i) {
+ xmlpp::Element* load_font = root->add_child("LoadFont");
+ load_font->set_attribute ("Id", (*i)->id);
+ load_font->set_attribute ("URI", (*i)->uri);
+ }
+
+ list<SubtitleString> sorted = _subtitles;
+ sorted.sort (SubtitleSorter ());
+
+ /* XXX: script, underlined, weight not supported */
+
+ optional<string> font;
+ bool italic = false;
+ Colour colour;
+ int size = 0;
+ float aspect_adjust = 1.0;
+ Effect effect = NONE;
+ Colour effect_colour;
+ int spot_number = 1;
+ Time last_in;
+ Time last_out;
+ Time last_fade_up_time;
+ Time last_fade_down_time;
+
+ xmlpp::Element* font_element = 0;
+ xmlpp::Element* subtitle_element = 0;
+
+ for (list<SubtitleString>::iterator i = sorted.begin(); i != sorted.end(); ++i) {
+
+ /* We will start a new <Font>...</Font> whenever some font property changes.
+ I suppose we should really make an optimal hierarchy of <Font> tags, but
+ that seems hard.
+ */
+
+ bool const font_changed =
+ font != i->font() ||
+ italic != i->italic() ||
+ colour != i->colour() ||
+ size != i->size() ||
+ fabs (aspect_adjust - i->aspect_adjust()) > ASPECT_ADJUST_EPSILON ||
+ effect != i->effect() ||
+ effect_colour != i->effect_colour();
+
+ if (font_changed) {
+ font = i->font ();
+ italic = i->italic ();
+ colour = i->colour ();
+ size = i->size ();
+ aspect_adjust = i->aspect_adjust ();
+ effect = i->effect ();
+ effect_colour = i->effect_colour ();
+ }
+
+ if (!font_element || font_changed) {
+ font_element = root->add_child ("Font");
+ if (font) {
+ font_element->set_attribute ("Id", font.get ());
+ }
+ font_element->set_attribute ("Italic", italic ? "yes" : "no");
+ font_element->set_attribute ("Color", colour.to_argb_string());
+ font_element->set_attribute ("Size", raw_convert<string> (size));
+ if (fabs (aspect_adjust - 1.0) > ASPECT_ADJUST_EPSILON) {
+ font_element->set_attribute ("AspectAdjust", raw_convert<string> (aspect_adjust));
+ }
+ font_element->set_attribute ("Effect", effect_to_string (effect));
+ font_element->set_attribute ("EffectColor", effect_colour.to_argb_string());
+ font_element->set_attribute ("Script", "normal");
+ font_element->set_attribute ("Underlined", "no");
+ font_element->set_attribute ("Weight", "normal");
+ }
+
+ if (!subtitle_element || font_changed ||
+ (last_in != i->in() ||
+ last_out != i->out() ||
+ last_fade_up_time != i->fade_up_time() ||
+ last_fade_down_time != i->fade_down_time()
+ )) {
+
+ subtitle_element = font_element->add_child ("Subtitle");
+ subtitle_element->set_attribute ("SpotNumber", raw_convert<string> (spot_number++));
+ subtitle_element->set_attribute ("TimeIn", i->in().as_string());
+ subtitle_element->set_attribute ("TimeOut", i->out().as_string());
+ subtitle_element->set_attribute ("FadeUpTime", raw_convert<string> (i->fade_up_time().as_editable_units(250)));
+ subtitle_element->set_attribute ("FadeDownTime", raw_convert<string> (i->fade_down_time().as_editable_units(250)));
+
+ last_in = i->in ();
+ last_out = i->out ();
+ last_fade_up_time = i->fade_up_time ();
+ last_fade_down_time = i->fade_down_time ();
+ }
+
+ xmlpp::Element* text = subtitle_element->add_child ("Text");
+ if (i->h_align() != HALIGN_CENTER) {
+ text->set_attribute ("HAlign", halign_to_string (i->h_align ()));
+ }
+ if (i->h_position() > ALIGN_EPSILON) {
+ text->set_attribute ("HPosition", raw_convert<string> (i->h_position() * 100, 6));
+ }
+ text->set_attribute ("VAlign", valign_to_string (i->v_align()));
+ text->set_attribute ("VPosition", raw_convert<string> (i->v_position() * 100, 6));
+ text->add_child_text (i->text());
+ }
+
+ return doc.write_to_string_formatted ("UTF-8");
+}
+
+void
+InteropSubtitleAsset::add_font (string id, string uri)
+{
+ _load_font_nodes.push_back (shared_ptr<InteropLoadFontNode> (new InteropLoadFontNode (id, uri)));
+}
+
+bool
+InteropSubtitleAsset::equals (shared_ptr<const Asset> other_asset, EqualityOptions options, NoteHandler note) const
+{
+ if (!SubtitleAsset::equals (other_asset, options, note)) {
+ return false;
+ }
+
+ shared_ptr<const InteropSubtitleAsset> other = dynamic_pointer_cast<const InteropSubtitleAsset> (other_asset);
+ if (!other) {
+ return false;
+ }
+
+ list<shared_ptr<InteropLoadFontNode> >::const_iterator i = _load_font_nodes.begin ();
+ list<shared_ptr<InteropLoadFontNode> >::const_iterator j = other->_load_font_nodes.begin ();
+
+ while (i != _load_font_nodes.end ()) {
+ if (j == other->_load_font_nodes.end ()) {
+ note (DCP_ERROR, "<LoadFont> nodes differ");
+ return false;
+ }
+
+ if (**i != **j) {
+ note (DCP_ERROR, "<LoadFont> nodes differ");
+ return false;
+ }
+
+ ++i;
+ ++j;
+ }
+
+ if (_movie_title != other->_movie_title) {
+ note (DCP_ERROR, "Subtitle movie titles differ");
+ return false;
+ }
+
+ return true;
+}
+
+list<shared_ptr<LoadFontNode> >
+InteropSubtitleAsset::load_font_nodes () const
+{
+ list<shared_ptr<LoadFontNode> > lf;
+ copy (_load_font_nodes.begin(), _load_font_nodes.end(), back_inserter (lf));
+ return lf;
+}
--- /dev/null
+/*
+ Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
+
+ 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
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "subtitle_asset.h"
+#include <boost/filesystem.hpp>
+
+namespace dcp {
+
+class InteropLoadFontNode;
+
+class InteropSubtitleAsset : public SubtitleAsset
+{
+public:
+ InteropSubtitleAsset (std::string movie_title, std::string language);
+ InteropSubtitleAsset (boost::filesystem::path file);
+
+ bool equals (
+ boost::shared_ptr<const Asset>,
+ EqualityOptions,
+ NoteHandler note
+ ) const;
+
+ std::list<boost::shared_ptr<LoadFontNode> > load_font_nodes () const;
+
+ void add_font (std::string id, std::string uri);
+
+ Glib::ustring xml_as_string () const;
+
+private:
+ std::string _movie_title;
+ std::list<boost::shared_ptr<InteropLoadFontNode> > _load_font_nodes;
+};
+
+}
+++ /dev/null
-/*
- Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
-
- 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
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#include "interop_subtitle_content.h"
-#include "interop_load_font_node.h"
-#include "xml.h"
-#include "raw_convert.h"
-#include "font_node.h"
-#include <libxml++/libxml++.h>
-#include <boost/foreach.hpp>
-#include <cmath>
-
-using std::list;
-using std::string;
-using std::cout;
-using boost::shared_ptr;
-using boost::optional;
-using boost::dynamic_pointer_cast;
-using namespace dcp;
-
-InteropSubtitleContent::InteropSubtitleContent (boost::filesystem::path file)
- : SubtitleContent (file)
-{
- shared_ptr<cxml::Document> xml (new cxml::Document ("DCSubtitle"));
- xml->read_file (file);
- _id = xml->string_child ("SubtitleID");
-
- _movie_title = xml->string_child ("MovieTitle");
- _load_font_nodes = type_children<dcp::InteropLoadFontNode> (xml, "LoadFont");
-
- list<cxml::NodePtr> f = xml->node_children ("Font");
- list<shared_ptr<dcp::FontNode> > font_nodes;
- BOOST_FOREACH (cxml::NodePtr& i, f) {
- font_nodes.push_back (shared_ptr<FontNode> (new FontNode (i, 250)));
- }
-
- parse_common (xml, font_nodes);
-}
-
-InteropSubtitleContent::InteropSubtitleContent (string movie_title, string language)
- : _movie_title (movie_title)
-{
- _language = language;
-}
-
-struct SubtitleSorter {
- bool operator() (SubtitleString const & a, SubtitleString const & b) {
- if (a.in() != b.in()) {
- return a.in() < b.in();
- }
- return a.v_position() < b.v_position();
- }
-};
-
-Glib::ustring
-InteropSubtitleContent::xml_as_string () const
-{
- xmlpp::Document doc;
- xmlpp::Element* root = doc.create_root_node ("DCSubtitle");
- root->set_attribute ("Version", "1.0");
-
- root->add_child("SubtitleID")->add_child_text (_id);
- root->add_child("MovieTitle")->add_child_text (_movie_title);
- root->add_child("ReelNumber")->add_child_text (raw_convert<string> (_reel_number));
- root->add_child("Language")->add_child_text (_language);
-
- for (list<shared_ptr<InteropLoadFontNode> >::const_iterator i = _load_font_nodes.begin(); i != _load_font_nodes.end(); ++i) {
- xmlpp::Element* load_font = root->add_child("LoadFont");
- load_font->set_attribute ("Id", (*i)->id);
- load_font->set_attribute ("URI", (*i)->uri);
- }
-
- list<SubtitleString> sorted = _subtitles;
- sorted.sort (SubtitleSorter ());
-
- /* XXX: script, underlined, weight not supported */
-
- optional<string> font;
- bool italic = false;
- Colour colour;
- int size = 0;
- float aspect_adjust = 1.0;
- Effect effect = NONE;
- Colour effect_colour;
- int spot_number = 1;
- Time last_in;
- Time last_out;
- Time last_fade_up_time;
- Time last_fade_down_time;
-
- xmlpp::Element* font_element = 0;
- xmlpp::Element* subtitle_element = 0;
-
- for (list<SubtitleString>::iterator i = sorted.begin(); i != sorted.end(); ++i) {
-
- /* We will start a new <Font>...</Font> whenever some font property changes.
- I suppose we should really make an optimal hierarchy of <Font> tags, but
- that seems hard.
- */
-
- bool const font_changed =
- font != i->font() ||
- italic != i->italic() ||
- colour != i->colour() ||
- size != i->size() ||
- fabs (aspect_adjust - i->aspect_adjust()) > ASPECT_ADJUST_EPSILON ||
- effect != i->effect() ||
- effect_colour != i->effect_colour();
-
- if (font_changed) {
- font = i->font ();
- italic = i->italic ();
- colour = i->colour ();
- size = i->size ();
- aspect_adjust = i->aspect_adjust ();
- effect = i->effect ();
- effect_colour = i->effect_colour ();
- }
-
- if (!font_element || font_changed) {
- font_element = root->add_child ("Font");
- if (font) {
- font_element->set_attribute ("Id", font.get ());
- }
- font_element->set_attribute ("Italic", italic ? "yes" : "no");
- font_element->set_attribute ("Color", colour.to_argb_string());
- font_element->set_attribute ("Size", raw_convert<string> (size));
- if (fabs (aspect_adjust - 1.0) > ASPECT_ADJUST_EPSILON) {
- font_element->set_attribute ("AspectAdjust", raw_convert<string> (aspect_adjust));
- }
- font_element->set_attribute ("Effect", effect_to_string (effect));
- font_element->set_attribute ("EffectColor", effect_colour.to_argb_string());
- font_element->set_attribute ("Script", "normal");
- font_element->set_attribute ("Underlined", "no");
- font_element->set_attribute ("Weight", "normal");
- }
-
- if (!subtitle_element || font_changed ||
- (last_in != i->in() ||
- last_out != i->out() ||
- last_fade_up_time != i->fade_up_time() ||
- last_fade_down_time != i->fade_down_time()
- )) {
-
- subtitle_element = font_element->add_child ("Subtitle");
- subtitle_element->set_attribute ("SpotNumber", raw_convert<string> (spot_number++));
- subtitle_element->set_attribute ("TimeIn", i->in().as_string());
- subtitle_element->set_attribute ("TimeOut", i->out().as_string());
- subtitle_element->set_attribute ("FadeUpTime", raw_convert<string> (i->fade_up_time().as_editable_units(250)));
- subtitle_element->set_attribute ("FadeDownTime", raw_convert<string> (i->fade_down_time().as_editable_units(250)));
-
- last_in = i->in ();
- last_out = i->out ();
- last_fade_up_time = i->fade_up_time ();
- last_fade_down_time = i->fade_down_time ();
- }
-
- xmlpp::Element* text = subtitle_element->add_child ("Text");
- if (i->h_align() != HALIGN_CENTER) {
- text->set_attribute ("HAlign", halign_to_string (i->h_align ()));
- }
- if (i->h_position() > ALIGN_EPSILON) {
- text->set_attribute ("HPosition", raw_convert<string> (i->h_position() * 100, 6));
- }
- text->set_attribute ("VAlign", valign_to_string (i->v_align()));
- text->set_attribute ("VPosition", raw_convert<string> (i->v_position() * 100, 6));
- text->add_child_text (i->text());
- }
-
- return doc.write_to_string_formatted ("UTF-8");
-}
-
-void
-InteropSubtitleContent::add_font (string id, string uri)
-{
- _load_font_nodes.push_back (shared_ptr<InteropLoadFontNode> (new InteropLoadFontNode (id, uri)));
-}
-
-bool
-InteropSubtitleContent::equals (shared_ptr<const Asset> other_asset, EqualityOptions options, NoteHandler note) const
-{
- if (!SubtitleContent::equals (other_asset, options, note)) {
- return false;
- }
-
- shared_ptr<const InteropSubtitleContent> other = dynamic_pointer_cast<const InteropSubtitleContent> (other_asset);
- if (!other) {
- return false;
- }
-
- list<shared_ptr<InteropLoadFontNode> >::const_iterator i = _load_font_nodes.begin ();
- list<shared_ptr<InteropLoadFontNode> >::const_iterator j = other->_load_font_nodes.begin ();
-
- while (i != _load_font_nodes.end ()) {
- if (j == other->_load_font_nodes.end ()) {
- note (DCP_ERROR, "<LoadFont> nodes differ");
- return false;
- }
-
- if (**i != **j) {
- note (DCP_ERROR, "<LoadFont> nodes differ");
- return false;
- }
-
- ++i;
- ++j;
- }
-
- if (_movie_title != other->_movie_title) {
- note (DCP_ERROR, "Subtitle movie titles differ");
- return false;
- }
-
- return true;
-}
-
-list<shared_ptr<LoadFontNode> >
-InteropSubtitleContent::load_font_nodes () const
-{
- list<shared_ptr<LoadFontNode> > lf;
- copy (_load_font_nodes.begin(), _load_font_nodes.end(), back_inserter (lf));
- return lf;
-}
+++ /dev/null
-/*
- Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
-
- 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
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#include "subtitle_content.h"
-#include <boost/filesystem.hpp>
-
-namespace dcp {
-
-class InteropLoadFontNode;
-
-class InteropSubtitleContent : public SubtitleContent
-{
-public:
- InteropSubtitleContent (std::string movie_title, std::string language);
- InteropSubtitleContent (boost::filesystem::path file);
-
- bool equals (
- boost::shared_ptr<const Asset>,
- EqualityOptions,
- NoteHandler note
- ) const;
-
- std::list<boost::shared_ptr<LoadFontNode> > load_font_nodes () const;
-
- void add_font (std::string id, std::string uri);
-
- Glib::ustring xml_as_string () const;
-
-private:
- std::string _movie_title;
- std::list<boost::shared_ptr<InteropLoadFontNode> > _load_font_nodes;
-};
-
-}
#include "mono_picture_mxf.h"
#include "stereo_picture_mxf.h"
#include "sound_mxf.h"
-#include "subtitle_content.h"
+#include "subtitle_asset.h"
#include "reel_mono_picture_asset.h"
#include "reel_stereo_picture_asset.h"
#include "reel_sound_asset.h"
using boost::shared_ptr;
using namespace dcp;
-ReelSoundAsset::ReelSoundAsset (shared_ptr<SoundMXF> content, int64_t entry_point)
- : ReelMXFAsset (content, content->edit_rate(), content->intrinsic_duration(), entry_point)
+ReelSoundAsset::ReelSoundAsset (shared_ptr<SoundMXF> asset, int64_t entry_point)
+ : ReelMXFAsset (asset, asset->edit_rate(), asset->intrinsic_duration(), entry_point)
{
}
* @brief ReelSubtitleAsset class.
*/
-#include "subtitle_content.h"
+#include "subtitle_asset.h"
#include "reel_subtitle_asset.h"
using std::string;
using boost::shared_ptr;
using namespace dcp;
-ReelSubtitleAsset::ReelSubtitleAsset (boost::shared_ptr<SubtitleContent> content, Fraction edit_rate, int64_t intrinsic_duration, int64_t entry_point)
- : ReelAsset (content, edit_rate, intrinsic_duration, entry_point)
+ReelSubtitleAsset::ReelSubtitleAsset (boost::shared_ptr<SubtitleAsset> asset, Fraction edit_rate, int64_t intrinsic_duration, int64_t entry_point)
+ : ReelAsset (asset, edit_rate, intrinsic_duration, entry_point)
{
}
/*
- Copyright (C) 2012-2014 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
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
#define LIBDCP_REEL_SUBTITLE_ASSET_H
#include "reel_asset.h"
-#include "subtitle_content.h"
+#include "subtitle_asset.h"
namespace dcp {
-class SubtitleContent;
+class SubtitleAsset;
/** @class ReelSubtitleAsset
* @brief Part of a Reel's description which refers to a subtitle XML file.
class ReelSubtitleAsset : public ReelAsset
{
public:
- ReelSubtitleAsset (boost::shared_ptr<SubtitleContent> content, Fraction edit_rate, int64_t instrinsic_duration, int64_t entry_point);
+ ReelSubtitleAsset (boost::shared_ptr<SubtitleAsset> asset, Fraction edit_rate, int64_t instrinsic_duration, int64_t entry_point);
ReelSubtitleAsset (boost::shared_ptr<const cxml::Node>);
- boost::shared_ptr<SubtitleContent> subtitle_content () const {
- return boost::dynamic_pointer_cast<SubtitleContent> (_asset.object ());
+ boost::shared_ptr<SubtitleAsset> subtitle_asset () const {
+ return boost::dynamic_pointer_cast<SubtitleAsset> (_asset.object ());
}
private:
--- /dev/null
+/*
+ Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
+
+ 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
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "smpte_subtitle_asset.h"
+#include "smpte_load_font_node.h"
+#include "font_node.h"
+#include "exceptions.h"
+#include "xml.h"
+#include "AS_DCP.h"
+#include "KM_util.h"
+#include <boost/foreach.hpp>
+
+using std::string;
+using std::list;
+using std::stringstream;
+using std::cout;
+using boost::shared_ptr;
+using namespace dcp;
+
+SMPTESubtitleAsset::SMPTESubtitleAsset (boost::filesystem::path file, bool mxf)
+ : SubtitleAsset (file)
+{
+ shared_ptr<cxml::Document> xml (new cxml::Document ("SubtitleReel"));
+
+ if (mxf) {
+ ASDCP::TimedText::MXFReader reader;
+ Kumu::Result_t r = reader.OpenRead (file.string().c_str ());
+ if (ASDCP_FAILURE (r)) {
+ boost::throw_exception (MXFFileError ("could not open MXF file for reading", file, r));
+ }
+
+ string s;
+ reader.ReadTimedTextResource (s, 0, 0);
+ stringstream t;
+ t << s;
+ xml->read_stream (t);
+
+ ASDCP::WriterInfo info;
+ reader.FillWriterInfo (info);
+
+ char buffer[64];
+ Kumu::bin2UUIDhex (info.AssetUUID, ASDCP::UUIDlen, buffer, sizeof (buffer));
+ _id = buffer;
+ } else {
+ xml->read_file (file);
+ _id = xml->string_child("Id").substr (9);
+ }
+
+ _load_font_nodes = type_children<dcp::SMPTELoadFontNode> (xml, "LoadFont");
+
+ int tcr = xml->number_child<int> ("TimeCodeRate");
+
+ shared_ptr<cxml::Node> subtitle_list = xml->optional_node_child ("SubtitleList");
+
+ list<cxml::NodePtr> f = subtitle_list->node_children ("Font");
+ list<shared_ptr<dcp::FontNode> > font_nodes;
+ BOOST_FOREACH (cxml::NodePtr& i, f) {
+ font_nodes.push_back (shared_ptr<FontNode> (new FontNode (i, tcr)));
+ }
+
+ parse_common (xml, font_nodes);
+}
+
+list<shared_ptr<LoadFontNode> >
+SMPTESubtitleAsset::load_font_nodes () const
+{
+ list<shared_ptr<LoadFontNode> > lf;
+ copy (_load_font_nodes.begin(), _load_font_nodes.end(), back_inserter (lf));
+ return lf;
+}
+
+bool
+SMPTESubtitleAsset::valid_mxf (boost::filesystem::path file)
+{
+ ASDCP::TimedText::MXFReader reader;
+ Kumu::Result_t r = reader.OpenRead (file.string().c_str ());
+ return !ASDCP_FAILURE (r);
+}
--- /dev/null
+/*
+ Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
+
+ 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
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "subtitle_asset.h"
+#include <boost/filesystem.hpp>
+
+namespace dcp {
+
+class SMPTELoadFontNode;
+
+class SMPTESubtitleAsset : public SubtitleAsset
+{
+public:
+ /** @param file File name
+ * @param mxf true if `file' is a MXF, or false if it is an XML file.
+ */
+ SMPTESubtitleAsset (boost::filesystem::path file, bool mxf = true);
+
+ std::list<boost::shared_ptr<LoadFontNode> > load_font_nodes () const;
+
+ static bool valid_mxf (boost::filesystem::path);
+
+private:
+ std::list<boost::shared_ptr<SMPTELoadFontNode> > _load_font_nodes;
+};
+
+}
+++ /dev/null
-/*
- Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
-
- 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
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#include "smpte_subtitle_content.h"
-#include "smpte_load_font_node.h"
-#include "font_node.h"
-#include "exceptions.h"
-#include "xml.h"
-#include "AS_DCP.h"
-#include "KM_util.h"
-#include <boost/foreach.hpp>
-
-using std::string;
-using std::list;
-using std::stringstream;
-using std::cout;
-using boost::shared_ptr;
-using namespace dcp;
-
-SMPTESubtitleContent::SMPTESubtitleContent (boost::filesystem::path file, bool mxf)
- : SubtitleContent (file)
-{
- shared_ptr<cxml::Document> xml (new cxml::Document ("SubtitleReel"));
-
- if (mxf) {
- ASDCP::TimedText::MXFReader reader;
- Kumu::Result_t r = reader.OpenRead (file.string().c_str ());
- if (ASDCP_FAILURE (r)) {
- boost::throw_exception (MXFFileError ("could not open MXF file for reading", file, r));
- }
-
- string s;
- reader.ReadTimedTextResource (s, 0, 0);
- stringstream t;
- t << s;
- xml->read_stream (t);
-
- ASDCP::WriterInfo info;
- reader.FillWriterInfo (info);
-
- char buffer[64];
- Kumu::bin2UUIDhex (info.AssetUUID, ASDCP::UUIDlen, buffer, sizeof (buffer));
- _id = buffer;
- } else {
- xml->read_file (file);
- _id = xml->string_child("Id").substr (9);
- }
-
- _load_font_nodes = type_children<dcp::SMPTELoadFontNode> (xml, "LoadFont");
-
- int tcr = xml->number_child<int> ("TimeCodeRate");
-
- shared_ptr<cxml::Node> subtitle_list = xml->optional_node_child ("SubtitleList");
-
- list<cxml::NodePtr> f = subtitle_list->node_children ("Font");
- list<shared_ptr<dcp::FontNode> > font_nodes;
- BOOST_FOREACH (cxml::NodePtr& i, f) {
- font_nodes.push_back (shared_ptr<FontNode> (new FontNode (i, tcr)));
- }
-
- parse_common (xml, font_nodes);
-}
-
-list<shared_ptr<LoadFontNode> >
-SMPTESubtitleContent::load_font_nodes () const
-{
- list<shared_ptr<LoadFontNode> > lf;
- copy (_load_font_nodes.begin(), _load_font_nodes.end(), back_inserter (lf));
- return lf;
-}
-
-bool
-SMPTESubtitleContent::valid_mxf (boost::filesystem::path file)
-{
- ASDCP::TimedText::MXFReader reader;
- Kumu::Result_t r = reader.OpenRead (file.string().c_str ());
- return !ASDCP_FAILURE (r);
-}
+++ /dev/null
-/*
- Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
-
- 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
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#include "subtitle_content.h"
-#include <boost/filesystem.hpp>
-
-namespace dcp {
-
-class SMPTELoadFontNode;
-
-class SMPTESubtitleContent : public SubtitleContent
-{
-public:
- /** @param file File name
- * @param mxf true if `file' is a MXF, or false if it is an XML file.
- */
- SMPTESubtitleContent (boost::filesystem::path file, bool mxf = true);
-
- std::list<boost::shared_ptr<LoadFontNode> > load_font_nodes () const;
-
- static bool valid_mxf (boost::filesystem::path);
-
-private:
- std::list<boost::shared_ptr<SMPTELoadFontNode> > _load_font_nodes;
-};
-
-}
--- /dev/null
+/*
+ Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
+
+ 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
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "raw_convert.h"
+#include "subtitle_asset.h"
+#include "util.h"
+#include "xml.h"
+#include "font_node.h"
+#include "text_node.h"
+#include "subtitle_string.h"
+#include "dcp_assert.h"
+#include "AS_DCP.h"
+#include "KM_util.h"
+#include <libxml++/nodes/element.h>
+#include <boost/algorithm/string.hpp>
+#include <fstream>
+
+using std::string;
+using std::list;
+using std::ostream;
+using std::ofstream;
+using std::stringstream;
+using std::cout;
+using boost::shared_ptr;
+using boost::optional;
+using boost::dynamic_pointer_cast;
+using namespace dcp;
+
+SubtitleAsset::SubtitleAsset ()
+ : _reel_number ("1")
+{
+
+}
+
+SubtitleAsset::SubtitleAsset (boost::filesystem::path file)
+ : Asset (file)
+ , _reel_number ("1")
+{
+
+}
+
+void
+SubtitleAsset::parse_common (shared_ptr<cxml::Document> xml, list<shared_ptr<dcp::FontNode> > font_nodes)
+{
+ _reel_number = xml->string_child ("ReelNumber");
+ _language = xml->string_child ("Language");
+
+ /* Now make Subtitle objects to represent the raw XML nodes
+ in a sane way.
+ */
+
+ ParseState parse_state;
+ examine_font_nodes (xml, font_nodes, parse_state);
+}
+
+void
+SubtitleAsset::examine_font_nodes (
+ shared_ptr<const cxml::Node> xml,
+ list<shared_ptr<dcp::FontNode> > const & font_nodes,
+ ParseState& parse_state
+ )
+{
+ for (list<shared_ptr<dcp::FontNode> >::const_iterator i = font_nodes.begin(); i != font_nodes.end(); ++i) {
+
+ parse_state.font_nodes.push_back (*i);
+ maybe_add_subtitle ((*i)->text, parse_state);
+
+ for (list<shared_ptr<dcp::SubtitleNode> >::iterator j = (*i)->subtitle_nodes.begin(); j != (*i)->subtitle_nodes.end(); ++j) {
+ parse_state.subtitle_nodes.push_back (*j);
+ examine_text_nodes (xml, (*j)->text_nodes, parse_state);
+ examine_font_nodes (xml, (*j)->font_nodes, parse_state);
+ parse_state.subtitle_nodes.pop_back ();
+ }
+
+ examine_font_nodes (xml, (*i)->font_nodes, parse_state);
+ examine_text_nodes (xml, (*i)->text_nodes, parse_state);
+
+ parse_state.font_nodes.pop_back ();
+ }
+}
+
+void
+SubtitleAsset::examine_text_nodes (
+ shared_ptr<const cxml::Node> xml,
+ list<shared_ptr<dcp::TextNode> > const & text_nodes,
+ ParseState& parse_state
+ )
+{
+ for (list<shared_ptr<dcp::TextNode> >::const_iterator i = text_nodes.begin(); i != text_nodes.end(); ++i) {
+ parse_state.text_nodes.push_back (*i);
+ maybe_add_subtitle ((*i)->text, parse_state);
+ examine_font_nodes (xml, (*i)->font_nodes, parse_state);
+ parse_state.text_nodes.pop_back ();
+ }
+}
+
+void
+SubtitleAsset::maybe_add_subtitle (string text, ParseState const & parse_state)
+{
+ if (empty_or_white_space (text)) {
+ return;
+ }
+
+ if (parse_state.text_nodes.empty() || parse_state.subtitle_nodes.empty ()) {
+ return;
+ }
+
+ DCP_ASSERT (!parse_state.text_nodes.empty ());
+ DCP_ASSERT (!parse_state.subtitle_nodes.empty ());
+
+ dcp::FontNode effective_font (parse_state.font_nodes);
+ dcp::TextNode effective_text (*parse_state.text_nodes.back ());
+ dcp::SubtitleNode effective_subtitle (*parse_state.subtitle_nodes.back ());
+
+ _subtitles.push_back (
+ SubtitleString (
+ effective_font.id,
+ effective_font.italic.get_value_or (false),
+ effective_font.colour.get_value_or (dcp::Colour (255, 255, 255)),
+ effective_font.size,
+ effective_font.aspect_adjust.get_value_or (1.0),
+ effective_subtitle.in,
+ effective_subtitle.out,
+ effective_text.h_position,
+ effective_text.h_align,
+ effective_text.v_position,
+ effective_text.v_align,
+ text,
+ effective_font.effect.get_value_or (NONE),
+ effective_font.effect_colour.get_value_or (dcp::Colour (0, 0, 0)),
+ effective_subtitle.fade_up_time,
+ effective_subtitle.fade_down_time
+ )
+ );
+}
+
+list<SubtitleString>
+SubtitleAsset::subtitles_during (Time from, Time to) const
+{
+ list<SubtitleString> s;
+ for (list<SubtitleString>::const_iterator i = _subtitles.begin(); i != _subtitles.end(); ++i) {
+ if (i->out() >= from && i->in() <= to) {
+ s.push_back (*i);
+ }
+ }
+
+ return s;
+}
+
+void
+SubtitleAsset::add (SubtitleString s)
+{
+ _subtitles.push_back (s);
+}
+
+void
+SubtitleAsset::write_xml (boost::filesystem::path p) const
+{
+ FILE* f = fopen_boost (p, "w");
+ if (!f) {
+ throw FileError ("Could not open file for writing", p, -1);
+ }
+
+ Glib::ustring const s = xml_as_string ();
+ fwrite (s.c_str(), 1, s.bytes(), f);
+ fclose (f);
+
+ _file = p;
+}
+
+Time
+SubtitleAsset::latest_subtitle_out () const
+{
+ Time t;
+ for (list<SubtitleString>::const_iterator i = _subtitles.begin(); i != _subtitles.end(); ++i) {
+ if (i->out() > t) {
+ t = i->out ();
+ }
+ }
+
+ return t;
+}
+
+bool
+SubtitleAsset::equals (shared_ptr<const Asset> other_asset, EqualityOptions options, NoteHandler note) const
+{
+ if (!Asset::equals (other_asset, options, note)) {
+ return false;
+ }
+
+ shared_ptr<const SubtitleAsset> other = dynamic_pointer_cast<const SubtitleAsset> (other_asset);
+ if (!other) {
+ return false;
+ }
+
+ if (_reel_number != other->_reel_number) {
+ note (DCP_ERROR, "subtitle reel numbers differ");
+ return false;
+ }
+
+ if (_language != other->_language) {
+ note (DCP_ERROR, "subtitle languages differ");
+ return false;
+ }
+
+ if (_subtitles != other->_subtitles) {
+ note (DCP_ERROR, "subtitles differ");
+ return false;
+ }
+
+ return true;
+}
--- /dev/null
+/*
+ Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
+
+ 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
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef LIBDCP_SUBTITLE_ASSET_H
+#define LIBDCP_SUBTITLE_ASSET_H
+
+#include "asset.h"
+#include "dcp_time.h"
+#include "subtitle_string.h"
+#include <libcxml/cxml.h>
+
+namespace dcp
+{
+
+class SubtitleString;
+class FontNode;
+class TextNode;
+class SubtitleNode;
+class LoadFontNode;
+
+/** @class SubtitleAsset
+ * @brief A parent for classes representing a file containing subtitles.
+ */
+class SubtitleAsset : public Asset
+{
+public:
+ SubtitleAsset ();
+ SubtitleAsset (boost::filesystem::path file);
+
+ bool equals (
+ boost::shared_ptr<const Asset>,
+ EqualityOptions,
+ NoteHandler note
+ ) const;
+
+ std::string language () const {
+ return _language;
+ }
+
+ std::list<SubtitleString> subtitles_during (Time from, Time to) const;
+ std::list<SubtitleString> const & subtitles () const {
+ return _subtitles;
+ }
+
+ void add (SubtitleString);
+
+ void write_xml (boost::filesystem::path) const;
+ virtual Glib::ustring xml_as_string () const {
+ /* XXX: this should be pure virtual when SMPTE writing is implemented */
+ return "";
+ }
+
+ Time latest_subtitle_out () const;
+
+ virtual std::list<boost::shared_ptr<LoadFontNode> > load_font_nodes () const = 0;
+
+protected:
+ void parse_common (boost::shared_ptr<cxml::Document> xml, std::list<boost::shared_ptr<FontNode> > font_nodes);
+
+ std::string pkl_type (Standard) const {
+ return "text/xml";
+ }
+
+ std::string asdcp_kind () const {
+ return "Subtitle";
+ }
+
+ /* strangely, this is sometimes a string */
+ std::string _reel_number;
+ std::string _language;
+
+ std::list<SubtitleString> _subtitles;
+
+private:
+ struct ParseState {
+ std::list<boost::shared_ptr<FontNode> > font_nodes;
+ std::list<boost::shared_ptr<TextNode> > text_nodes;
+ std::list<boost::shared_ptr<SubtitleNode> > subtitle_nodes;
+ };
+
+ void maybe_add_subtitle (std::string text, ParseState const & parse_state);
+
+ void examine_font_nodes (
+ boost::shared_ptr<const cxml::Node> xml,
+ std::list<boost::shared_ptr<FontNode> > const & font_nodes,
+ ParseState& parse_state
+ );
+
+ void examine_text_nodes (
+ boost::shared_ptr<const cxml::Node> xml,
+ std::list<boost::shared_ptr<TextNode> > const & text_nodes,
+ ParseState& parse_state
+ );
+};
+
+}
+
+#endif
+++ /dev/null
-/*
- Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
-
- 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
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#include "raw_convert.h"
-#include "subtitle_content.h"
-#include "util.h"
-#include "xml.h"
-#include "font_node.h"
-#include "text_node.h"
-#include "subtitle_string.h"
-#include "dcp_assert.h"
-#include "AS_DCP.h"
-#include "KM_util.h"
-#include <libxml++/nodes/element.h>
-#include <boost/algorithm/string.hpp>
-#include <fstream>
-
-using std::string;
-using std::list;
-using std::ostream;
-using std::ofstream;
-using std::stringstream;
-using std::cout;
-using boost::shared_ptr;
-using boost::optional;
-using boost::dynamic_pointer_cast;
-using namespace dcp;
-
-SubtitleContent::SubtitleContent ()
- : _reel_number ("1")
-{
-
-}
-
-SubtitleContent::SubtitleContent (boost::filesystem::path file)
- : Asset (file)
- , _reel_number ("1")
-{
-
-}
-
-void
-SubtitleContent::parse_common (shared_ptr<cxml::Document> xml, list<shared_ptr<dcp::FontNode> > font_nodes)
-{
- _reel_number = xml->string_child ("ReelNumber");
- _language = xml->string_child ("Language");
-
- /* Now make Subtitle objects to represent the raw XML nodes
- in a sane way.
- */
-
- ParseState parse_state;
- examine_font_nodes (xml, font_nodes, parse_state);
-}
-
-void
-SubtitleContent::examine_font_nodes (
- shared_ptr<const cxml::Node> xml,
- list<shared_ptr<dcp::FontNode> > const & font_nodes,
- ParseState& parse_state
- )
-{
- for (list<shared_ptr<dcp::FontNode> >::const_iterator i = font_nodes.begin(); i != font_nodes.end(); ++i) {
-
- parse_state.font_nodes.push_back (*i);
- maybe_add_subtitle ((*i)->text, parse_state);
-
- for (list<shared_ptr<dcp::SubtitleNode> >::iterator j = (*i)->subtitle_nodes.begin(); j != (*i)->subtitle_nodes.end(); ++j) {
- parse_state.subtitle_nodes.push_back (*j);
- examine_text_nodes (xml, (*j)->text_nodes, parse_state);
- examine_font_nodes (xml, (*j)->font_nodes, parse_state);
- parse_state.subtitle_nodes.pop_back ();
- }
-
- examine_font_nodes (xml, (*i)->font_nodes, parse_state);
- examine_text_nodes (xml, (*i)->text_nodes, parse_state);
-
- parse_state.font_nodes.pop_back ();
- }
-}
-
-void
-SubtitleContent::examine_text_nodes (
- shared_ptr<const cxml::Node> xml,
- list<shared_ptr<dcp::TextNode> > const & text_nodes,
- ParseState& parse_state
- )
-{
- for (list<shared_ptr<dcp::TextNode> >::const_iterator i = text_nodes.begin(); i != text_nodes.end(); ++i) {
- parse_state.text_nodes.push_back (*i);
- maybe_add_subtitle ((*i)->text, parse_state);
- examine_font_nodes (xml, (*i)->font_nodes, parse_state);
- parse_state.text_nodes.pop_back ();
- }
-}
-
-void
-SubtitleContent::maybe_add_subtitle (string text, ParseState const & parse_state)
-{
- if (empty_or_white_space (text)) {
- return;
- }
-
- if (parse_state.text_nodes.empty() || parse_state.subtitle_nodes.empty ()) {
- return;
- }
-
- DCP_ASSERT (!parse_state.text_nodes.empty ());
- DCP_ASSERT (!parse_state.subtitle_nodes.empty ());
-
- dcp::FontNode effective_font (parse_state.font_nodes);
- dcp::TextNode effective_text (*parse_state.text_nodes.back ());
- dcp::SubtitleNode effective_subtitle (*parse_state.subtitle_nodes.back ());
-
- _subtitles.push_back (
- SubtitleString (
- effective_font.id,
- effective_font.italic.get_value_or (false),
- effective_font.colour.get_value_or (dcp::Colour (255, 255, 255)),
- effective_font.size,
- effective_font.aspect_adjust.get_value_or (1.0),
- effective_subtitle.in,
- effective_subtitle.out,
- effective_text.h_position,
- effective_text.h_align,
- effective_text.v_position,
- effective_text.v_align,
- text,
- effective_font.effect.get_value_or (NONE),
- effective_font.effect_colour.get_value_or (dcp::Colour (0, 0, 0)),
- effective_subtitle.fade_up_time,
- effective_subtitle.fade_down_time
- )
- );
-}
-
-list<SubtitleString>
-SubtitleContent::subtitles_during (Time from, Time to) const
-{
- list<SubtitleString> s;
- for (list<SubtitleString>::const_iterator i = _subtitles.begin(); i != _subtitles.end(); ++i) {
- if (i->out() >= from && i->in() <= to) {
- s.push_back (*i);
- }
- }
-
- return s;
-}
-
-void
-SubtitleContent::add (SubtitleString s)
-{
- _subtitles.push_back (s);
-}
-
-void
-SubtitleContent::write_xml (boost::filesystem::path p) const
-{
- FILE* f = fopen_boost (p, "w");
- if (!f) {
- throw FileError ("Could not open file for writing", p, -1);
- }
-
- Glib::ustring const s = xml_as_string ();
- fwrite (s.c_str(), 1, s.bytes(), f);
- fclose (f);
-
- _file = p;
-}
-
-Time
-SubtitleContent::latest_subtitle_out () const
-{
- Time t;
- for (list<SubtitleString>::const_iterator i = _subtitles.begin(); i != _subtitles.end(); ++i) {
- if (i->out() > t) {
- t = i->out ();
- }
- }
-
- return t;
-}
-
-bool
-SubtitleContent::equals (shared_ptr<const Asset> other_asset, EqualityOptions options, NoteHandler note) const
-{
- if (!Asset::equals (other_asset, options, note)) {
- return false;
- }
-
- shared_ptr<const SubtitleContent> other = dynamic_pointer_cast<const SubtitleContent> (other_asset);
- if (!other) {
- return false;
- }
-
- if (_reel_number != other->_reel_number) {
- note (DCP_ERROR, "subtitle reel numbers differ");
- return false;
- }
-
- if (_language != other->_language) {
- note (DCP_ERROR, "subtitle languages differ");
- return false;
- }
-
- if (_subtitles != other->_subtitles) {
- note (DCP_ERROR, "subtitles differ");
- return false;
- }
-
- return true;
-}
+++ /dev/null
-/*
- Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
-
- 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
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#ifndef LIBDCP_SUBTITLE_CONTENT_H
-#define LIBDCP_SUBTITLE_CONTENT_H
-
-#include "asset.h"
-#include "dcp_time.h"
-#include "subtitle_string.h"
-#include <libcxml/cxml.h>
-
-namespace dcp
-{
-
-class SubtitleString;
-class FontNode;
-class TextNode;
-class SubtitleNode;
-class LoadFontNode;
-
-/** @class SubtitleContent
- * @brief A parent for classes representing a file containing subtitles.
- */
-class SubtitleContent : public Asset
-{
-public:
- SubtitleContent ();
- SubtitleContent (boost::filesystem::path file);
-
- bool equals (
- boost::shared_ptr<const Asset>,
- EqualityOptions,
- NoteHandler note
- ) const;
-
- std::string language () const {
- return _language;
- }
-
- std::list<SubtitleString> subtitles_during (Time from, Time to) const;
- std::list<SubtitleString> const & subtitles () const {
- return _subtitles;
- }
-
- void add (SubtitleString);
-
- void write_xml (boost::filesystem::path) const;
- virtual Glib::ustring xml_as_string () const {
- /* XXX: this should be pure virtual when SMPTE writing is implemented */
- return "";
- }
-
- Time latest_subtitle_out () const;
-
- virtual std::list<boost::shared_ptr<LoadFontNode> > load_font_nodes () const = 0;
-
-protected:
- void parse_common (boost::shared_ptr<cxml::Document> xml, std::list<boost::shared_ptr<FontNode> > font_nodes);
-
- std::string pkl_type (Standard) const {
- return "text/xml";
- }
-
- std::string asdcp_kind () const {
- return "Subtitle";
- }
-
- /* strangely, this is sometimes a string */
- std::string _reel_number;
- std::string _language;
-
- std::list<SubtitleString> _subtitles;
-
-private:
- struct ParseState {
- std::list<boost::shared_ptr<FontNode> > font_nodes;
- std::list<boost::shared_ptr<TextNode> > text_nodes;
- std::list<boost::shared_ptr<SubtitleNode> > subtitle_nodes;
- };
-
- void maybe_add_subtitle (std::string text, ParseState const & parse_state);
-
- void examine_font_nodes (
- boost::shared_ptr<const cxml::Node> xml,
- std::list<boost::shared_ptr<FontNode> > const & font_nodes,
- ParseState& parse_state
- );
-
- void examine_text_nodes (
- boost::shared_ptr<const cxml::Node> xml,
- std::list<boost::shared_ptr<TextNode> > const & text_nodes,
- ParseState& parse_state
- );
-};
-
-}
-
-#endif
font_node.cc
gamma_transfer_function.cc
interop_load_font_node.cc
- interop_subtitle_content.cc
+ interop_subtitle_asset.cc
key.cc
local_time.cc
metadata.cc
rgb_xyz.cc
signer.cc
smpte_load_font_node.cc
- smpte_subtitle_content.cc
+ smpte_subtitle_asset.cc
sound_mxf.cc
sound_mxf_writer.cc
sound_frame.cc
stereo_picture_mxf_writer.cc
stereo_picture_frame.cc
subtitle_node.cc
- subtitle_content.cc
+ subtitle_asset.cc
subtitle_string.cc
text_node.cc
transfer_function.cc
font.h
gamma_transfer_function.h
interop_load_font_node.h
- interop_subtitle_content.h
+ interop_subtitle_asset.h
key.h
load_font_node.h
local_time.h
ref.h
signer.h
smpte_load_font_node.h
- smpte_subtitle_content.h
+ smpte_subtitle_asset.h
sound_frame.h
sound_mxf.h
sound_mxf_writer.h
stereo_picture_mxf.h
stereo_picture_frame.h
subtitle_node.h
- subtitle_content.h
+ subtitle_asset.h
subtitle_string.h
transfer_function.h
types.h
/*
- Copyright (C) 2013-2014 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2013-2015 Carl Hetherington <cth@carlh.net>
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
#include "picture_mxf_writer.h"
#include "sound_mxf_writer.h"
#include "sound_mxf.h"
-#include "subtitle_content.h"
#include "reel.h"
#include "test.h"
#include "file.h"
#include "reel.h"
#include "test.h"
#include "file.h"
-#include "subtitle_content.h"
+#include "subtitle_asset.h"
#include "reel_mono_picture_asset.h"
#include "reel_sound_asset.h"
#include "encrypted_kdm.h"
/*
- Copyright (C) 2012-2014 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
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
*/
-#include "interop_subtitle_content.h"
+#include "interop_subtitle_asset.h"
#include "subtitle_string.h"
#include <boost/test/unit_test.hpp>
/* Load some subtitle content from XML and check that it is read correctly */
BOOST_AUTO_TEST_CASE (read_subtitle_test1)
{
- dcp::InteropSubtitleContent subs ("test/data/subs1.xml");
+ dcp::InteropSubtitleAsset subs ("test/data/subs1.xml");
BOOST_CHECK_EQUAL (subs.language(), "French");
/** And similarly for another one */
BOOST_AUTO_TEST_CASE (read_subtitle_test2)
{
- dcp::InteropSubtitleContent subs ("test/data/subs2.xml");
+ dcp::InteropSubtitleAsset subs ("test/data/subs2.xml");
list<dcp::SubtitleString> s = subs.subtitles_during (dcp::Time (0, 0, 42, 100, 250), dcp::Time (0, 0, 42, 101, 250));
BOOST_REQUIRE_EQUAL (s.size(), 2);
#include "dcp.h"
#include "cpl.h"
#include "reel.h"
-#include "subtitle_content.h"
+#include "subtitle_asset.h"
#include "reel_subtitle_asset.h"
#include "exceptions.h"
for (list<shared_ptr<Reel> >::iterator j = reels.begin(); j != reels.end(); ++j) {
if ((*j)->main_subtitle()) {
- (*j)->main_subtitle()->subtitle_content()->write_xml ((*j)->main_subtitle()->subtitle_content()->file ());
+ (*j)->main_subtitle()->subtitle_asset()->write_xml ((*j)->main_subtitle()->subtitle_asset()->file ());
}
}
}
*/
-#include "smpte_subtitle_content.h"
+#include "smpte_subtitle_asset.h"
#include "test.h"
#include <boost/test/unit_test.hpp>
/** Load a SMPTE XML subtitle file */
BOOST_AUTO_TEST_CASE (smpte_subtitle_test)
{
- dcp::SMPTESubtitleContent sc (private_test / "8dfafe11-2bd1-4206-818b-afc109cfe7f6_reel1.xml", false);
+ dcp::SMPTESubtitleAsset sc (private_test / "8dfafe11-2bd1-4206-818b-afc109cfe7f6_reel1.xml", false);
BOOST_REQUIRE_EQUAL (sc.id(), "8dfafe11-2bd1-4206-818b-afc109cfe7f6");
BOOST_REQUIRE_EQUAL (sc.subtitles().size(), 159);
/*
- Copyright (C) 2012-2014 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
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
*/
-#include "interop_subtitle_content.h"
+#include "interop_subtitle_asset.h"
#include <iostream>
using namespace std;
exit (EXIT_FAILURE);
}
- dcp::InteropSubtitleContent s (argv[1]);
+ dcp::InteropSubtitleAsset s (argv[1]);
cout << s.xml_as_string ();
return 0;
}
*/
-#include "interop_subtitle_content.h"
+#include "interop_subtitle_asset.h"
#include "subtitle_string.h"
#include "test.h"
#include <boost/test/unit_test.hpp>
/* Write some subtitle content as Interop XML and check that it is right */
BOOST_AUTO_TEST_CASE (write_subtitle_test)
{
- dcp::InteropSubtitleContent c ("Test", "EN");
+ dcp::InteropSubtitleAsset c ("Test", "EN");
c.add (
dcp::SubtitleString (
#include "reel.h"
#include "sound_mxf.h"
#include "picture_mxf.h"
-#include "subtitle_content.h"
+#include "subtitle_asset.h"
#include "reel_picture_asset.h"
#include "reel_sound_asset.h"
#include "reel_subtitle_asset.h"
return;
}
- list<SubtitleString> subs = reel->main_subtitle()->subtitle_content()->subtitles ();
- cout << " Subtitle: " << subs.size() << " subtitles in " << reel->main_subtitle()->subtitle_content()->language() << "\n";
+ list<SubtitleString> subs = reel->main_subtitle()->subtitle_asset()->subtitles ();
+ cout << " Subtitle: " << subs.size() << " subtitles in " << reel->main_subtitle()->subtitle_asset()->language() << "\n";
if (list_subtitles) {
BOOST_FOREACH (SubtitleString const& k, subs) {
cout << k << "\n";