+ doc.write_to_file_formatted (file.string(), "UTF-8");
+
+ set_file (file);
+}
+
+
+void
+CPL::read_composition_metadata_asset (cxml::ConstNodePtr node)
+{
+ auto fctt = node->node_child("FullContentTitleText");
+ _full_content_title_text = fctt->content();
+ _full_content_title_text_language = fctt->optional_string_attribute("language");
+
+ _release_territory = node->optional_string_child("ReleaseTerritory");
+ if (_release_territory) {
+ _release_territory_scope = node->node_child("ReleaseTerritory")->optional_string_attribute("scope");
+ }
+
+ auto vn = node->optional_node_child("VersionNumber");
+ if (vn) {
+ _version_number = raw_convert<int>(vn->content());
+ /* I decided to check for this number being non-negative on being set, and in the verifier, but not here */
+ auto vn_status = vn->optional_string_attribute("status");
+ if (vn_status) {
+ _status = string_to_status (*vn_status);
+ }
+ }
+
+ _chain = node->optional_string_child("Chain");
+ _distributor = node->optional_string_child("Distributor");
+ _facility = node->optional_string_child("Facility");
+
+ auto acv = node->optional_node_child("AlternateContentVersionList");
+ if (acv) {
+ for (auto i: acv->node_children("ContentVersion")) {
+ _content_versions.push_back (ContentVersion(i));
+ }
+ }
+
+ auto lum = node->optional_node_child("Luminance");
+ if (lum) {
+ _luminance = Luminance (lum);
+ }
+
+ _main_sound_configuration = node->optional_string_child("MainSoundConfiguration");
+
+ auto sr = node->optional_string_child("MainSoundSampleRate");
+ if (sr) {
+ vector<string> sr_bits;
+ boost::split (sr_bits, *sr, boost::is_any_of(" "));
+ DCP_ASSERT (sr_bits.size() == 2);
+ _main_sound_sample_rate = raw_convert<int>(sr_bits[0]);
+ }
+
+ _main_picture_stored_area = dcp::Size (
+ node->node_child("MainPictureStoredArea")->number_child<int>("Width"),
+ node->node_child("MainPictureStoredArea")->number_child<int>("Height")
+ );
+
+ _main_picture_active_area = dcp::Size (
+ node->node_child("MainPictureActiveArea")->number_child<int>("Width"),
+ node->node_child("MainPictureActiveArea")->number_child<int>("Height")
+ );
+
+ auto sll = node->optional_string_child("MainSubtitleLanguageList");
+ if (sll) {
+ vector<string> sll_split;
+ boost::split (sll_split, *sll, boost::is_any_of(" "));
+ DCP_ASSERT (!sll_split.empty());
+
+ /* If the first language on SubtitleLanguageList is the same as the language of the first subtitle we'll ignore it */
+ size_t first = 0;
+ if (!_reels.empty()) {
+ auto sub = _reels.front()->main_subtitle();
+ if (sub) {
+ auto lang = sub->language();
+ if (lang && lang == sll_split[0]) {
+ first = 1;
+ }
+ }
+ }
+
+ for (auto i = first; i < sll_split.size(); ++i) {
+ _additional_subtitle_languages.push_back (sll_split[i]);
+ }
+ }
+}
+
+
+/** Write a CompositionMetadataAsset node as a child of @param node provided
+ * the required metadata is stored in the object. If any required metadata
+ * is missing this method will do nothing.
+ */
+void
+CPL::maybe_write_composition_metadata_asset (xmlpp::Element* node) const
+{
+ if (
+ !_main_sound_configuration ||
+ !_main_sound_sample_rate ||
+ !_main_picture_stored_area ||
+ !_main_picture_active_area ||
+ _reels.empty() ||
+ !_reels.front()->main_picture()) {
+ return;
+ }
+
+ auto meta = node->add_child("meta:CompositionMetadataAsset");
+ meta->set_namespace_declaration (cpl_metadata_ns, "meta");
+
+ meta->add_child("Id")->add_child_text("urn:uuid:" + make_uuid());
+
+ auto mp = _reels.front()->main_picture();
+ meta->add_child("EditRate")->add_child_text(mp->edit_rate().as_string());
+ meta->add_child("IntrinsicDuration")->add_child_text(raw_convert<string>(mp->intrinsic_duration()));
+
+ auto fctt = meta->add_child("FullContentTitleText", "meta");
+ if (_full_content_title_text) {
+ fctt->add_child_text (*_full_content_title_text);
+ }
+ if (_full_content_title_text_language) {
+ fctt->set_attribute("language", *_full_content_title_text_language);
+ }
+
+ if (_release_territory) {
+ meta->add_child("ReleaseTerritory", "meta")->add_child_text(*_release_territory);
+ }
+
+ if (_version_number) {
+ xmlpp::Element* vn = meta->add_child("VersionNumber", "meta");
+ vn->add_child_text(raw_convert<string>(*_version_number));
+ if (_status) {
+ vn->set_attribute("status", status_to_string(*_status));
+ }
+ }
+
+ if (_chain) {
+ meta->add_child("Chain", "meta")->add_child_text(*_chain);
+ }
+
+ if (_distributor) {
+ meta->add_child("Distributor", "meta")->add_child_text(*_distributor);
+ }
+
+ if (_facility) {
+ meta->add_child("Facility", "meta")->add_child_text(*_facility);
+ }
+
+ if (_content_versions.size() > 1) {
+ xmlpp::Element* vc = meta->add_child("AlternateContentVersionList", "meta");
+ for (size_t i = 1; i < _content_versions.size(); ++i) {
+ _content_versions[i].as_xml (vc);
+ }
+ }
+
+ if (_luminance) {
+ _luminance->as_xml (meta, "meta");
+ }
+
+ meta->add_child("MainSoundConfiguration", "meta")->add_child_text(*_main_sound_configuration);
+ meta->add_child("MainSoundSampleRate", "meta")->add_child_text(raw_convert<string>(*_main_sound_sample_rate) + " 1");
+
+ auto stored = meta->add_child("MainPictureStoredArea", "meta");
+ stored->add_child("Width", "meta")->add_child_text(raw_convert<string>(_main_picture_stored_area->width));
+ stored->add_child("Height", "meta")->add_child_text(raw_convert<string>(_main_picture_stored_area->height));
+
+ auto active = meta->add_child("MainPictureActiveArea", "meta");
+ active->add_child("Width", "meta")->add_child_text(raw_convert<string>(_main_picture_active_area->width));
+ active->add_child("Height", "meta")->add_child_text(raw_convert<string>(_main_picture_active_area->height));
+
+ optional<string> first_subtitle_language;
+ for (auto i: _reels) {
+ if (i->main_subtitle()) {
+ first_subtitle_language = i->main_subtitle()->language();
+ if (first_subtitle_language) {
+ break;
+ }
+ }
+ }
+
+ if (first_subtitle_language || !_additional_subtitle_languages.empty()) {
+ string lang;
+ if (first_subtitle_language) {
+ lang = *first_subtitle_language;
+ }
+ for (auto const& i: _additional_subtitle_languages) {
+ if (!lang.empty()) {
+ lang += " ";
+ }
+ lang += i;
+ }
+ meta->add_child("MainSubtitleLanguageList", "meta")->add_child_text(lang);
+ }