using namespace dcp::dc;
Package::Package (boost::filesystem::path directory)
- : dcp::Package (directory)
+ : dcp::Package<CPL> (directory)
{
}
-void
-Package::read (bool keep_going, ReadErrors* errors)
-{
- list<shared_ptr<dcp::Asset> > other_assets;
-
- BOOST_FOREACH (shared_ptr<dcp::Asset> i, read_assetmap (keep_going, errors)) {
- shared_ptr<CPL> cpl = dynamic_pointer_cast<CPL> (i);
- if (cpl) {
- _cpls.push_back (cpl);
- } else {
- other_assets.push_back (i);
- }
- }
-
- BOOST_FOREACH (shared_ptr<CPL> i, cpls ()) {
- i->resolve_refs (other_assets);
- }
-}
-
-void
-Package::resolve_refs (list<shared_ptr<dcp::Asset> > assets)
-{
- BOOST_FOREACH (shared_ptr<CPL> i, cpls ()) {
- i->resolve_refs (assets);
- }
-}
-
bool
Package::equals (Package const & other, dcp::EqualityOptions opt, dcp::NoteHandler note) const
{
return p.string ();
}
-/** Write the VOLINDEX file.
- * @param standard DCP standard to use (INTEROP or SMPTE)
- */
-void
-Package::write_volindex (Standard standard) const
-{
- boost::filesystem::path p = _directory;
- switch (standard) {
- case DCP_INTEROP:
- p /= "VOLINDEX";
- break;
- case DCP_SMPTE:
- p /= "VOLINDEX.xml";
- break;
- case IMP:
- /* XXX */
- DCP_ASSERT (false);
- break;
- }
-
- xmlpp::Document doc;
- xmlpp::Element* root = 0;
-
- switch (standard) {
- case DCP_INTEROP:
- root = doc.create_root_node ("VolumeIndex", "http://www.digicine.com/PROTO-ASDCP-AM-20040311#");
- break;
- case DCP_SMPTE:
- case IMP:
- root = doc.create_root_node ("VolumeIndex", "http://www.smpte-ra.org/schemas/429-9/2007/AM");
- break;
- }
-
- root->add_child("Index")->add_child_text ("1");
- doc.write_to_file (p.string (), "UTF-8");
-}
-
-void
-Package::write_assetmap (Standard standard, string pkl_uuid, int pkl_length, dcp::XMLMetadata metadata) const
-{
- boost::filesystem::path p = _directory;
-
- switch (standard) {
- case DCP_INTEROP:
- p /= "ASSETMAP";
- break;
- case DCP_SMPTE:
- case IMP:
- p /= "ASSETMAP.xml";
- break;
- }
-
- xmlpp::Document doc;
- xmlpp::Element* root = 0;
-
- switch (standard) {
- case DCP_INTEROP:
- root = doc.create_root_node ("AssetMap", "http://www.digicine.com/PROTO-ASDCP-AM-20040311#");
- break;
- case DCP_SMPTE:
- case IMP:
- root = doc.create_root_node ("AssetMap", "http://www.smpte-ra.org/schemas/429-9/2007/AM");
- break;
- }
-
- root->add_child("Id")->add_child_text ("urn:uuid:" + make_uuid());
- root->add_child("AnnotationText")->add_child_text ("Created by " + metadata.creator);
-
- switch (standard) {
- case DCP_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);
- break;
- case DCP_SMPTE:
- case IMP:
- 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);
- break;
- }
-
- xmlpp::Node* asset_list = root->add_child ("AssetList");
-
- xmlpp::Node* asset = asset_list->add_child ("Asset");
- asset->add_child("Id")->add_child_text ("urn:uuid:" + pkl_uuid);
- asset->add_child("PackingList")->add_child_text ("true");
- xmlpp::Node* chunk_list = asset->add_child ("ChunkList");
- xmlpp::Node* chunk = chunk_list->add_child ("Chunk");
- chunk->add_child("Path")->add_child_text ("pkl_" + pkl_uuid + ".xml");
- chunk->add_child("VolumeIndex")->add_child_text ("1");
- chunk->add_child("Offset")->add_child_text ("0");
- chunk->add_child("Length")->add_child_text (raw_convert<string> (pkl_length));
-
- BOOST_FOREACH (shared_ptr<dcp::Asset> i, assets ()) {
- i->write_to_assetmap (asset_list, _directory);
- }
-
- /* This must not be the _formatted version otherwise signature digests will be wrong */
- doc.write_to_file (p.string (), "UTF-8");
-}
-
/** Write all the XML files for this DCP.
* @param standand INTEROP or SMPTE.
* @param metadata Metadata to use for PKL and asset map files.
/** @class Package
* @brief A class to create or read a DCP.
*/
-class Package : public dcp::Package
+class Package : public dcp::Package<CPL>
{
public:
/** Construct a DCP package. You can pass an existing DCP's directory
*/
Package (boost::filesystem::path directory);
- /** Read the DCP's structure into this object.
- * @param keep_going true to try to keep going in the face of (some) errors.
- * @param errors List of errors that will be added to if keep_going is true.
- */
- void read (bool keep_going = false, ReadErrors* errors = 0);
-
/** Compare this DCP with another, according to various options.
* @param other DCP to compare this one to.
* @param options Options to define what "equality" means.
boost::shared_ptr<const CertificateChain> signer
) const;
- void write_volindex (Standard standard) const;
-
- /** Write the ASSETMAP file.
- * @param pkl_uuid UUID of our PKL.
- * @param pkl_length Length of our PKL in bytes.
- */
- void write_assetmap (Standard standard, std::string pkl_uuid, int pkl_length, XMLMetadata metadata) const;
-
boost::shared_ptr<dcp::Asset> xml_asset_factory (boost::filesystem::path file, std::string root) const;
boost::shared_ptr<dcp::Asset> mxf_asset_factory (boost::filesystem::path file) const;
-
- /** the CPLs that make up this DCP */
- std::list<boost::shared_ptr<CPL> > _cpls;
};
}
using namespace dcp::im;
Package::Package (boost::filesystem::path directory)
- : dcp::Package (directory)
+ : dcp::Package<CPL> (directory)
{
}
+
+list<Asset>
+Package::assets () const
+{
+ /* XXX */
+ return list<Asset> ();
+}
namespace dcp {
namespace im {
-class Package : public dcp::Package
+class Package : public dcp::Package<CPL>
{
public:
Package (boost::filesystem::path directory);
+
+ std::list<boost::shared_ptr<Asset> > assets () const;
};
}
+++ /dev/null
-/*
- Copyright (C) 2012-2016 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 "package.h"
-#include "compose.hpp"
-#include "exceptions.h"
-#include "util.h"
-#include "font_asset.h"
-#include <libcxml/cxml.h>
-#include <libxml++/libxml++.h>
-#include <boost/foreach.hpp>
-#include <boost/algorithm/string.hpp>
-
-using std::list;
-using std::map;
-using std::string;
-using boost::shared_ptr;
-using boost::algorithm::starts_with;
-using namespace dcp;
-
-Package::Package (boost::filesystem::path directory)
-{
- if (!boost::filesystem::exists (directory)) {
- boost::filesystem::create_directories (directory);
- }
-
- _directory = boost::filesystem::canonical (directory);
-}
-
-list<shared_ptr<Asset> >
-Package::read_assetmap (bool keep_going, ReadErrors* errors) const
-{
- boost::filesystem::path asset_map_file;
- if (boost::filesystem::exists (_directory / "ASSETMAP")) {
- asset_map_file = _directory / "ASSETMAP";
- } else if (boost::filesystem::exists (_directory / "ASSETMAP.xml")) {
- asset_map_file = _directory / "ASSETMAP.xml";
- } else {
- boost::throw_exception (PackageReadError (String::compose ("could not find AssetMap file in `%1'", _directory.string())));
- }
-
- cxml::Document asset_map ("AssetMap");
- asset_map.read_file (asset_map_file);
- list<shared_ptr<cxml::Node> > asset_nodes = asset_map.node_child("AssetList")->node_children ("Asset");
- map<string, boost::filesystem::path> paths;
- BOOST_FOREACH (shared_ptr<cxml::Node> i, asset_nodes) {
- if (i->node_child("ChunkList")->node_children("Chunk").size() != 1) {
- boost::throw_exception (XMLError ("unsupported asset chunk count"));
- }
- string p = i->node_child("ChunkList")->node_child("Chunk")->string_child ("Path");
- if (starts_with (p, "file://")) {
- p = p.substr (7);
- }
- paths.insert (make_pair (remove_urn_uuid (i->string_child ("Id")), p));
- }
-
- /* Read all the assets from the asset map */
- /* XXX: I think we should be looking at the PKL here to decide type, not
- the extension of the file.
- */
-
- list<shared_ptr<Asset> > assets;
-
- for (map<string, boost::filesystem::path>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
- boost::filesystem::path path = _directory / i->second;
-
- if (!boost::filesystem::exists (path)) {
- if (keep_going) {
- if (errors) {
- errors->push_back (shared_ptr<MissingAssetError> (new MissingAssetError (path)));
- }
- } else {
- throw MissingAssetError (path);
- }
- continue;
- }
-
- if (boost::filesystem::extension(path) == ".xml") {
- xmlpp::DomParser* p = new xmlpp::DomParser;
- try {
- p->parse_file (path.string());
- } catch (std::exception& e) {
- delete p;
- continue;
- }
-
- string const root = p->get_document()->get_root_node()->get_name ();
- delete p;
-
- shared_ptr<Asset> a = xml_asset_factory (path, root);
- if (a) {
- assets.push_back (a);
- }
- } else if (boost::filesystem::extension (path) == ".mxf") {
- assets.push_back (mxf_asset_factory (path));
- } else if (boost::filesystem::extension (path) == ".ttf") {
- assets.push_back (shared_ptr<FontAsset> (new FontAsset (i->first, path)));
- }
- }
-
- return assets;
-}
#ifndef LIBDCP_PACKAGE_H
#define LIBDCP_PACKAGE_H
-#include "exceptions.h"
-#include <boost/filesystem.hpp>
+#include "package_base.h"
+#include "dc_cpl.h"
+#include <boost/foreach.hpp>
namespace dcp {
class Asset;
-class Package
+template <class T>
+class Package : public PackageBase
{
public:
- Package (boost::filesystem::path directory);
-
- typedef std::list<boost::shared_ptr<PackageReadError> > ReadErrors;
+ Package (boost::filesystem::path directory)
+ : PackageBase (directory)
+ {
+
+ }
+
+ void read (bool keep_going = false, ReadErrors* errors = 0)
+ {
+ std::list<boost::shared_ptr<dcp::Asset> > other_assets;
+
+ BOOST_FOREACH (boost::shared_ptr<dcp::Asset> i, read_assetmap (keep_going, errors)) {
+ boost::shared_ptr<T> cpl = boost::dynamic_pointer_cast<T> (i);
+ if (cpl) {
+ _cpls.push_back (cpl);
+ } else {
+ other_assets.push_back (i);
+ }
+ }
+
+ BOOST_FOREACH (boost::shared_ptr<T> i, _cpls) {
+ i->resolve_refs (other_assets);
+ }
+ }
+
+ void resolve_refs (std::list<boost::shared_ptr<dcp::Asset> > assets)
+ {
+ BOOST_FOREACH (boost::shared_ptr<T> i, _cpls) {
+ i->resolve_refs (assets);
+ }
+ }
protected:
-
- virtual boost::shared_ptr<Asset> xml_asset_factory (boost::filesystem::path file, std::string root) const = 0;
- virtual boost::shared_ptr<Asset> mxf_asset_factory (boost::filesystem::path file) const = 0;
-
- std::list<boost::shared_ptr<Asset> > read_assetmap (bool keep_going, ReadErrors* errors) const;
-
- /** the directory that the package is in */
- boost::filesystem::path _directory;
+ /** the CPLs that make up this package */
+ std::list<boost::shared_ptr<T> > _cpls;
};
}
--- /dev/null
+/*
+ Copyright (C) 2012-2016 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 "package_base.h"
+#include "compose.hpp"
+#include "exceptions.h"
+#include "util.h"
+#include "dcp_assert.h"
+#include "font_asset.h"
+#include "raw_convert.h"
+#include <libcxml/cxml.h>
+#include <libxml++/libxml++.h>
+#include <boost/foreach.hpp>
+#include <boost/algorithm/string.hpp>
+
+using std::list;
+using std::map;
+using std::string;
+using boost::shared_ptr;
+using boost::algorithm::starts_with;
+using namespace dcp;
+
+PackageBase::PackageBase (boost::filesystem::path directory)
+{
+ if (!boost::filesystem::exists (directory)) {
+ boost::filesystem::create_directories (directory);
+ }
+
+ _directory = boost::filesystem::canonical (directory);
+}
+
+list<shared_ptr<Asset> >
+PackageBase::read_assetmap (bool keep_going, ReadErrors* errors) const
+{
+ boost::filesystem::path asset_map_file;
+ if (boost::filesystem::exists (_directory / "ASSETMAP")) {
+ asset_map_file = _directory / "ASSETMAP";
+ } else if (boost::filesystem::exists (_directory / "ASSETMAP.xml")) {
+ asset_map_file = _directory / "ASSETMAP.xml";
+ } else {
+ boost::throw_exception (PackageReadError (String::compose ("could not find AssetMap file in `%1'", _directory.string())));
+ }
+
+ cxml::Document asset_map ("AssetMap");
+ asset_map.read_file (asset_map_file);
+ list<shared_ptr<cxml::Node> > asset_nodes = asset_map.node_child("AssetList")->node_children ("Asset");
+ map<string, boost::filesystem::path> paths;
+ BOOST_FOREACH (shared_ptr<cxml::Node> i, asset_nodes) {
+ if (i->node_child("ChunkList")->node_children("Chunk").size() != 1) {
+ boost::throw_exception (XMLError ("unsupported asset chunk count"));
+ }
+ string p = i->node_child("ChunkList")->node_child("Chunk")->string_child ("Path");
+ if (starts_with (p, "file://")) {
+ p = p.substr (7);
+ }
+ paths.insert (make_pair (remove_urn_uuid (i->string_child ("Id")), p));
+ }
+
+ /* Read all the assets from the asset map */
+ /* XXX: I think we should be looking at the PKL here to decide type, not
+ the extension of the file.
+ */
+
+ list<shared_ptr<Asset> > assets;
+
+ for (map<string, boost::filesystem::path>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
+ boost::filesystem::path path = _directory / i->second;
+
+ if (!boost::filesystem::exists (path)) {
+ if (keep_going) {
+ if (errors) {
+ errors->push_back (shared_ptr<MissingAssetError> (new MissingAssetError (path)));
+ }
+ } else {
+ throw MissingAssetError (path);
+ }
+ continue;
+ }
+
+ if (boost::filesystem::extension(path) == ".xml") {
+ xmlpp::DomParser* p = new xmlpp::DomParser;
+ try {
+ p->parse_file (path.string());
+ } catch (std::exception& e) {
+ delete p;
+ continue;
+ }
+
+ string const root = p->get_document()->get_root_node()->get_name ();
+ delete p;
+
+ shared_ptr<Asset> a = xml_asset_factory (path, root);
+ if (a) {
+ assets.push_back (a);
+ }
+ } else if (boost::filesystem::extension (path) == ".mxf") {
+ assets.push_back (mxf_asset_factory (path));
+ } else if (boost::filesystem::extension (path) == ".ttf") {
+ assets.push_back (shared_ptr<FontAsset> (new FontAsset (i->first, path)));
+ }
+ }
+
+ return assets;
+}
+
+
+/** Write the VOLINDEX file.
+ * @param standard DCP standard to use (INTEROP or SMPTE)
+ */
+void
+PackageBase::write_volindex (Standard standard) const
+{
+ boost::filesystem::path p = _directory;
+ switch (standard) {
+ case DCP_INTEROP:
+ p /= "VOLINDEX";
+ break;
+ case DCP_SMPTE:
+ p /= "VOLINDEX.xml";
+ break;
+ case IMP:
+ /* XXX */
+ DCP_ASSERT (false);
+ break;
+ }
+
+ xmlpp::Document doc;
+ xmlpp::Element* root = 0;
+
+ switch (standard) {
+ case DCP_INTEROP:
+ root = doc.create_root_node ("VolumeIndex", "http://www.digicine.com/PROTO-ASDCP-AM-20040311#");
+ break;
+ case DCP_SMPTE:
+ case IMP:
+ root = doc.create_root_node ("VolumeIndex", "http://www.smpte-ra.org/schemas/429-9/2007/AM");
+ break;
+ }
+
+ root->add_child("Index")->add_child_text ("1");
+ doc.write_to_file (p.string (), "UTF-8");
+}
+
+void
+PackageBase::write_assetmap (Standard standard, string pkl_uuid, int pkl_length, dcp::XMLMetadata metadata) const
+{
+ boost::filesystem::path p = _directory;
+
+ switch (standard) {
+ case DCP_INTEROP:
+ p /= "ASSETMAP";
+ break;
+ case DCP_SMPTE:
+ case IMP:
+ p /= "ASSETMAP.xml";
+ break;
+ }
+
+ xmlpp::Document doc;
+ xmlpp::Element* root = 0;
+
+ switch (standard) {
+ case DCP_INTEROP:
+ root = doc.create_root_node ("AssetMap", "http://www.digicine.com/PROTO-ASDCP-AM-20040311#");
+ break;
+ case DCP_SMPTE:
+ case IMP:
+ root = doc.create_root_node ("AssetMap", "http://www.smpte-ra.org/schemas/429-9/2007/AM");
+ break;
+ }
+
+ root->add_child("Id")->add_child_text ("urn:uuid:" + make_uuid());
+ root->add_child("AnnotationText")->add_child_text ("Created by " + metadata.creator);
+
+ switch (standard) {
+ case DCP_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);
+ break;
+ case DCP_SMPTE:
+ case IMP:
+ 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);
+ break;
+ }
+
+ xmlpp::Node* asset_list = root->add_child ("AssetList");
+
+ xmlpp::Node* asset = asset_list->add_child ("Asset");
+ asset->add_child("Id")->add_child_text ("urn:uuid:" + pkl_uuid);
+ asset->add_child("PackingList")->add_child_text ("true");
+ xmlpp::Node* chunk_list = asset->add_child ("ChunkList");
+ xmlpp::Node* chunk = chunk_list->add_child ("Chunk");
+ chunk->add_child("Path")->add_child_text ("pkl_" + pkl_uuid + ".xml");
+ chunk->add_child("VolumeIndex")->add_child_text ("1");
+ chunk->add_child("Offset")->add_child_text ("0");
+ chunk->add_child("Length")->add_child_text (raw_convert<string> (pkl_length));
+
+ BOOST_FOREACH (shared_ptr<dcp::Asset> i, assets ()) {
+ i->write_to_assetmap (asset_list, _directory);
+ }
+
+ /* This must not be the _formatted version otherwise signature digests will be wrong */
+ doc.write_to_file (p.string (), "UTF-8");
+}
--- /dev/null
+/*
+ Copyright (C) 2012-2016 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_PACKAGE_BASE_H
+#define LIBDCP_PACKAGE_BASE_H
+
+#include "exceptions.h"
+#include "types.h"
+#include "metadata.h"
+#include <boost/filesystem.hpp>
+
+namespace dcp {
+
+class Asset;
+
+class PackageBase
+{
+public:
+ PackageBase (boost::filesystem::path directory);
+
+ typedef std::list<boost::shared_ptr<PackageReadError> > ReadErrors;
+
+ virtual std::list<boost::shared_ptr<Asset> > assets () const = 0;
+
+protected:
+
+ virtual boost::shared_ptr<Asset> xml_asset_factory (boost::filesystem::path file, std::string root) const = 0;
+ virtual boost::shared_ptr<Asset> mxf_asset_factory (boost::filesystem::path file) const = 0;
+
+ std::list<boost::shared_ptr<Asset> > read_assetmap (bool keep_going, ReadErrors* errors) const;
+
+ void write_volindex (Standard standard) const;
+
+ /** Write the ASSETMAP file.
+ * @param pkl_uuid UUID of our PKL.
+ * @param pkl_length Length of our PKL in bytes.
+ */
+ void write_assetmap (Standard standard, std::string pkl_uuid, int pkl_length, XMLMetadata metadata) const;
+
+ /** the directory that the package is in */
+ boost::filesystem::path _directory;
+};
+
+}
+
+#endif
asset_writer.cc
object.cc
openjpeg_image.cc
- package.cc
+ package_base.cc
picture_asset.cc
picture_asset_writer.cc
reel.cc
void
dcp::filter_errors (dcp::dc::Package::ReadErrors& errors, bool ignore_missing_assets)
{
- for (Package::ReadErrors::iterator i = errors.begin(); i != errors.end(); ) {
+ for (PackageBase::ReadErrors::iterator i = errors.begin(); i != errors.end(); ) {
- Package::ReadErrors::iterator tmp = i;
+ PackageBase::ReadErrors::iterator tmp = i;
++tmp;
if (ignore_missing_assets && dynamic_pointer_cast<MissingAssetError> (*i)) {