X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Fdcp.cc;h=03d1598d6dc8d396269d17ec3b91d9da931be869;hb=65013fcc46474df4c11f69b674e79af465688531;hp=c7634b5d3385d1a9cafd5b847dffd41dd4540d66;hpb=8526058d24faec5f83ffd66758fef8d8c8159f73;p=libdcp.git diff --git a/src/dcp.cc b/src/dcp.cc index c7634b5d..03d1598d 100644 --- a/src/dcp.cc +++ b/src/dcp.cc @@ -27,9 +27,12 @@ #include #include #include +#include #include #include #include +#include +#include #include "dcp.h" #include "asset.h" #include "sound_asset.h" @@ -42,38 +45,43 @@ #include "parse/asset_map.h" #include "reel.h" #include "cpl.h" +#include "signer.h" +#include "kdm.h" using std::string; using std::list; using std::stringstream; using std::ofstream; using std::ostream; +using std::copy; +using std::back_inserter; +using std::make_pair; using boost::shared_ptr; using boost::lexical_cast; using namespace libdcp; -DCP::DCP (string directory) +DCP::DCP (boost::filesystem::path directory) : _directory (directory) { boost::filesystem::create_directories (directory); } void -DCP::write_xml (XMLMetadata const & metadata) const +DCP::write_xml (bool interop, XMLMetadata const & metadata, shared_ptr signer) const { - for (list >::const_iterator i = _cpls.begin(); i != _cpls.end(); ++i) { - (*i)->write_xml (metadata); + for (list >::const_iterator i = _cpls.begin(); i != _cpls.end(); ++i) { + (*i)->write_xml (interop, metadata, signer); } string pkl_uuid = make_uuid (); - string pkl_path = write_pkl (pkl_uuid, metadata); + string pkl_path = write_pkl (pkl_uuid, interop, metadata, signer); write_volindex (); - write_assetmap (pkl_uuid, boost::filesystem::file_size (pkl_path), metadata); + write_assetmap (pkl_uuid, boost::filesystem::file_size (pkl_path), interop, metadata); } std::string -DCP::write_pkl (string pkl_uuid, XMLMetadata const & metadata) const +DCP::write_pkl (string pkl_uuid, bool interop, XMLMetadata const & metadata, shared_ptr signer) const { assert (!_cpls.empty ()); @@ -84,26 +92,38 @@ DCP::write_pkl (string pkl_uuid, XMLMetadata const & metadata) const p /= s.str(); xmlpp::Document doc; - xmlpp::Element* root = doc.create_root_node ("PackingList", "http://www.smpte-ra.org/schemas/429-8/2007/PKL"); + xmlpp::Element* pkl; + if (interop) { + pkl = doc.create_root_node("PackingList", "http://www.digicine.com/PROTO-ASDCP-PKL-20040311#"); + } else { + pkl = doc.create_root_node("PackingList", "http://www.smpte-ra.org/schemas/429-8/2007/PKL"); + } + + if (signer) { + pkl->set_namespace_declaration ("http://www.w3.org/2000/09/xmldsig#", "dsig"); + } - root->add_child("Id")->add_child_text ("urn:uuid:" + pkl_uuid); + pkl->add_child("Id")->add_child_text ("urn:uuid:" + pkl_uuid); /* XXX: this is a bit of a hack */ - root->add_child("AnnotationText")->add_child_text (_cpls.front()->name()); - root->add_child("IssueDate")->add_child_text (metadata.issue_date); - root->add_child("Issuer")->add_child_text (metadata.issuer); - root->add_child("Creator")->add_child_text (metadata.creator); - - xmlpp::Node* asset_list = root->add_child ("AssetList"); + pkl->add_child("AnnotationText")->add_child_text(_cpls.front()->name()); + pkl->add_child("IssueDate")->add_child_text (metadata.issue_date); + pkl->add_child("Issuer")->add_child_text (metadata.issuer); + pkl->add_child("Creator")->add_child_text (metadata.creator); + xmlpp::Element* asset_list = pkl->add_child("AssetList"); list > a = assets (); for (list >::const_iterator i = a.begin(); i != a.end(); ++i) { (*i)->write_to_pkl (asset_list); } - - for (list >::const_iterator i = _cpls.begin(); i != _cpls.end(); ++i) { + + for (list >::const_iterator i = _cpls.begin(); i != _cpls.end(); ++i) { (*i)->write_to_pkl (asset_list); } + if (signer) { + signer->sign (pkl, interop); + } + doc.write_to_file_formatted (p.string (), "UTF-8"); return p.string (); } @@ -122,20 +142,34 @@ DCP::write_volindex () const } void -DCP::write_assetmap (string pkl_uuid, int pkl_length, XMLMetadata const & metadata) const +DCP::write_assetmap (string pkl_uuid, int pkl_length, bool interop, XMLMetadata const & metadata) const { boost::filesystem::path p; p /= _directory; p /= "ASSETMAP.xml"; xmlpp::Document doc; - xmlpp::Element* root = doc.create_root_node ("AssetMap", "http://www.smpte-ra.org/schemas/429-9/2007/AM"); + xmlpp::Element* root; + if (interop) { + root = doc.create_root_node ("AssetMap", "http://www.digicine.com/PROTO-ASDCP-AM-20040311#"); + } else { + root = doc.create_root_node ("AssetMap", "http://www.smpte-ra.org/schemas/429-9/2007/AM"); + } root->add_child("Id")->add_child_text ("urn:uuid:" + make_uuid()); - root->add_child("Creator")->add_child_text (metadata.creator); - root->add_child("VolumeCount")->add_child_text ("1"); - root->add_child("IssueDate")->add_child_text (metadata.issue_date); - root->add_child("Issuer")->add_child_text (metadata.issuer); + root->add_child("AnnotationText")->add_child_text ("Created by " + metadata.creator); + if (interop) { + root->add_child("VolumeCount")->add_child_text ("1"); + root->add_child("IssueDate")->add_child_text (metadata.issue_date); + root->add_child("Issuer")->add_child_text (metadata.issuer); + root->add_child("Creator")->add_child_text (metadata.creator); + } else { + root->add_child("Creator")->add_child_text (metadata.creator); + root->add_child("VolumeCount")->add_child_text ("1"); + root->add_child("IssueDate")->add_child_text (metadata.issue_date); + root->add_child("Issuer")->add_child_text (metadata.issuer); + } + xmlpp::Node* asset_list = root->add_child ("AssetList"); xmlpp::Node* asset = asset_list->add_child ("Asset"); @@ -148,7 +182,7 @@ DCP::write_assetmap (string pkl_uuid, int pkl_length, XMLMetadata const & metada chunk->add_child("Offset")->add_child_text ("0"); chunk->add_child("Length")->add_child_text (lexical_cast (pkl_length)); - for (list >::const_iterator i = _cpls.begin(); i != _cpls.end(); ++i) { + for (list >::const_iterator i = _cpls.begin(); i != _cpls.end(); ++i) { (*i)->write_to_assetmap (asset_list); } @@ -160,12 +194,16 @@ DCP::write_assetmap (string pkl_uuid, int pkl_length, XMLMetadata const & metada doc.write_to_file_formatted (p.string (), "UTF-8"); } - void DCP::read (bool require_mxfs) { - Files files; + read_assets (); + read_cpls (require_mxfs); +} +void +DCP::read_assets () +{ shared_ptr asset_map; try { boost::filesystem::path p = _directory; @@ -183,7 +221,7 @@ DCP::read (bool require_mxfs) } } catch (FileError& e) { - boost::throw_exception (FileError ("could not load AssetMap file", files.asset_map)); + boost::throw_exception (FileError ("could not load AssetMap file", _files.asset_map)); } for (list >::const_iterator i = asset_map->assets.begin(); i != asset_map->assets.end(); ++i) { @@ -210,36 +248,39 @@ DCP::read (bool require_mxfs) delete p; if (root == "CompositionPlaylist") { - files.cpls.push_back (t.string()); + _files.cpls.push_back (t.string()); } else if (root == "PackingList") { - if (files.pkl.empty ()) { - files.pkl = t.string(); + if (_files.pkl.empty ()) { + _files.pkl = t.string(); } else { boost::throw_exception (DCPReadError ("duplicate PKLs found")); } } } - if (files.cpls.empty ()) { + if (_files.cpls.empty ()) { boost::throw_exception (FileError ("no CPL files found", "")); } - if (files.pkl.empty ()) { + if (_files.pkl.empty ()) { boost::throw_exception (FileError ("no PKL file found", "")); } shared_ptr pkl; try { - pkl.reset (new parse::PKL (files.pkl)); + pkl.reset (new parse::PKL (_files.pkl)); } catch (FileError& e) { - boost::throw_exception (FileError ("could not load PKL file", files.pkl)); + boost::throw_exception (FileError ("could not load PKL file", _files.pkl)); } - /* Cross-check */ - /* XXX */ + _asset_maps.push_back (make_pair (boost::filesystem::absolute (_directory).string(), asset_map)); +} - for (list::iterator i = files.cpls.begin(); i != files.cpls.end(); ++i) { - _cpls.push_back (shared_ptr (new CPL (_directory, *i, asset_map, require_mxfs))); +void +DCP::read_cpls (bool require_mxfs) +{ + for (list::iterator i = _files.cpls.begin(); i != _files.cpls.end(); ++i) { + _cpls.push_back (shared_ptr (new CPL (_directory, *i, _asset_maps, require_mxfs))); } } @@ -251,8 +292,8 @@ DCP::equals (DCP const & other, EqualityOptions opt, boost::function >::const_iterator a = _cpls.begin (); - list >::const_iterator b = other._cpls.begin (); + list >::const_iterator a = _cpls.begin (); + list >::const_iterator b = other._cpls.begin (); while (a != _cpls.end ()) { if (!(*a)->equals (*b->get(), opt, note)) { @@ -265,7 +306,6 @@ DCP::equals (DCP const & other, EqualityOptions opt, boost::function cpl) { @@ -284,13 +324,44 @@ list > DCP::assets () const { list > a; - for (list >::const_iterator i = _cpls.begin(); i != _cpls.end(); ++i) { + for (list >::const_iterator i = _cpls.begin(); i != _cpls.end(); ++i) { list > t = (*i)->assets (); a.merge (t); } - a.sort (); + a.sort (AssetComparator ()); a.unique (); return a; } +bool +DCP::encrypted () const +{ + for (list >::const_iterator i = _cpls.begin(); i != _cpls.end(); ++i) { + if ((*i)->encrypted ()) { + return true; + } + } + + return false; +} + +void +DCP::add_kdm (KDM const & kdm) +{ + list keys = kdm.keys (); + + for (list >::iterator i = _cpls.begin(); i != _cpls.end(); ++i) { + for (list::iterator j = keys.begin(); j != keys.end(); ++j) { + if (j->cpl_id() == (*i)->id()) { + (*i)->add_kdm (kdm); + } + } + } +} + +void +DCP::add_assets_from (DCP const & ov) +{ + copy (ov._asset_maps.begin(), ov._asset_maps.end(), back_inserter (_asset_maps)); +}