diff options
| author | Carl Hetherington <cth@carlh.net> | 2016-05-24 23:02:38 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2016-05-24 23:02:38 +0100 |
| commit | cb7c3db37d196b6e9ddad60937bd5314a95eadb2 (patch) | |
| tree | b686e05142b39208e4af8ab0a01e3b47c5256378 /src | |
| parent | 096b175a661234d9e02a852cce9f56c4577b8259 (diff) | |
| parent | 85c699d29aab7ca7f7218b3f7f859e10c9025e37 (diff) | |
Merge branch '1.0' of ssh://main.carlh.net/home/carl/git/libdcp into 1.0
Diffstat (limited to 'src')
| -rw-r--r-- | src/colour_conversion.cc | 38 | ||||
| -rw-r--r-- | src/colour_conversion.h | 2 | ||||
| -rw-r--r-- | src/cpl.cc | 15 | ||||
| -rw-r--r-- | src/cpl.h | 7 | ||||
| -rw-r--r-- | src/dcp.cc | 43 | ||||
| -rw-r--r-- | src/dcp.h | 8 | ||||
| -rw-r--r-- | src/exceptions.cc | 6 | ||||
| -rw-r--r-- | src/exceptions.h | 6 | ||||
| -rw-r--r-- | src/modified_gamma_transfer_function.h | 7 |
9 files changed, 122 insertions, 10 deletions
diff --git a/src/colour_conversion.cc b/src/colour_conversion.cc index 8c48c2e1..46bc717e 100644 --- a/src/colour_conversion.cc +++ b/src/colour_conversion.cc @@ -97,6 +97,44 @@ ColourConversion::p3_to_xyz () return *c; } +ColourConversion const & +ColourConversion::rec1886_to_xyz () +{ + /* According to Olivier on DCP-o-matic bug #832, Rec. 1886 is Rec. 709 with + 2.4 gamma, so here goes ... + */ + static ColourConversion* c = new ColourConversion ( + shared_ptr<const TransferFunction> (new GammaTransferFunction (2.4)), + YUV_TO_RGB_REC709, + Chromaticity (0.64, 0.33), + Chromaticity (0.3, 0.6), + Chromaticity (0.15, 0.06), + /* D65 */ + Chromaticity (0.3127, 0.329), + optional<Chromaticity> (), + shared_ptr<const TransferFunction> (new GammaTransferFunction (2.6)) + ); + return *c; +} + +ColourConversion const & +ColourConversion::rec2020_to_xyz () +{ + /* From Wikipedia */ + static ColourConversion* c = new ColourConversion ( + shared_ptr<const TransferFunction> (new ModifiedGammaTransferFunction (1 / 0.45, 0.08145, 0.0993, 4.5)), + YUV_TO_RGB_REC709, + Chromaticity (0.708, 0.292), + Chromaticity (0.170, 0.797), + Chromaticity (0.131, 0.046), + /* D65 */ + Chromaticity (0.3127, 0.329), + optional<Chromaticity> (), + shared_ptr<const TransferFunction> (new GammaTransferFunction (2.6)) + ); + return *c; +} + ColourConversion::ColourConversion ( shared_ptr<const TransferFunction> in, YUVToRGB yuv_to_rgb, diff --git a/src/colour_conversion.h b/src/colour_conversion.h index 47071dd1..f974a182 100644 --- a/src/colour_conversion.h +++ b/src/colour_conversion.h @@ -139,6 +139,8 @@ public: static ColourConversion const & rec601_to_xyz (); static ColourConversion const & rec709_to_xyz (); static ColourConversion const & p3_to_xyz (); + static ColourConversion const & rec1886_to_xyz (); + static ColourConversion const & rec2020_to_xyz (); protected: /** Input transfer function (probably a gamma function, or something similar) */ @@ -45,6 +45,9 @@ using boost::optional; using boost::dynamic_pointer_cast; using namespace dcp; +static string const cpl_interop_ns = "http://www.digicine.com/PROTO-ASDCP-CPL-20040511#"; +static string const cpl_smpte_ns = "http://www.smpte-ra.org/schemas/429-7/2006/CPL"; + CPL::CPL (string annotation_text, ContentKind content_kind) : _annotation_text (annotation_text) /* default _content_title_text to _annotation_text */ @@ -67,6 +70,14 @@ CPL::CPL (boost::filesystem::path file) cxml::Document f ("CompositionPlaylist"); f.read_file (file); + if (f.namespace_uri() == cpl_interop_ns) { + _standard = INTEROP; + } else if (f.namespace_uri() == cpl_smpte_ns) { + _standard = SMPTE; + } else { + boost::throw_exception (XMLError ("Unrecognised CPL namespace " + f.namespace_uri())); + } + _id = remove_urn_uuid (f.string_child ("Id")); _annotation_text = f.optional_string_child ("AnnotationText").get_value_or (""); _metadata.issuer = f.optional_string_child ("Issuer").get_value_or (""); @@ -110,9 +121,9 @@ CPL::write_xml (boost::filesystem::path file, Standard standard, shared_ptr<cons xmlpp::Document doc; xmlpp::Element* root; if (standard == INTEROP) { - root = doc.create_root_node ("CompositionPlaylist", "http://www.digicine.com/PROTO-ASDCP-CPL-20040511#"); + root = doc.create_root_node ("CompositionPlaylist", cpl_interop_ns); } else { - root = doc.create_root_node ("CompositionPlaylist", "http://www.smpte-ra.org/schemas/429-7/2006/CPL"); + root = doc.create_root_node ("CompositionPlaylist", cpl_smpte_ns); } if (signer) { @@ -114,6 +114,10 @@ public: int64_t duration () const; + boost::optional<Standard> standard () const { + return _standard; + } + protected: /** @return type string for PKLs for this asset */ std::string pkl_type (Standard standard) const; @@ -129,6 +133,9 @@ private: std::string _content_version_id; ///< <Id> in <ContentVersion> std::string _content_version_label_text; ///< <LabelText> in <ContentVersion> std::list<boost::shared_ptr<Reel> > _reels; + + /** Standard of CPL that was read in */ + boost::optional<Standard> _standard; }; } @@ -64,6 +64,13 @@ using boost::dynamic_pointer_cast; using boost::algorithm::starts_with; using namespace dcp; +static string const assetmap_interop_ns = "http://www.digicine.com/PROTO-ASDCP-AM-20040311#"; +static string const assetmap_smpte_ns = "http://www.smpte-ra.org/schemas/429-9/2007/AM"; +static string const pkl_interop_ns = "http://www.digicine.com/PROTO-ASDCP-PKL-20040311#"; +static string const pkl_smpte_ns = "http://www.smpte-ra.org/schemas/429-8/2007/PKL"; +static string const volindex_interop_ns = "http://www.digicine.com/PROTO-ASDCP-AM-20040311#"; +static string const volindex_smpte_ns = "http://www.smpte-ra.org/schemas/429-9/2007/AM"; + DCP::DCP (boost::filesystem::path directory) : _directory (directory) { @@ -74,6 +81,7 @@ DCP::DCP (boost::filesystem::path directory) _directory = boost::filesystem::canonical (_directory); } +/** Call this instead of throwing an exception if the error can be tolerated */ template<class T> void survivable_error (bool keep_going, dcp::DCP::ReadErrors* errors, T const & e) { @@ -101,7 +109,16 @@ DCP::read (bool keep_going, ReadErrors* errors, bool ignore_incorrect_picture_mx } cxml::Document asset_map ("AssetMap"); + asset_map.read_file (asset_map_file); + if (asset_map.namespace_uri() == assetmap_interop_ns) { + _standard = INTEROP; + } else if (asset_map.namespace_uri() == assetmap_smpte_ns) { + _standard = SMPTE; + } else { + boost::throw_exception (XMLError ("Unrecognised Assetmap namespace " + asset_map.namespace_uri())); + } + 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) { @@ -146,11 +163,23 @@ DCP::read (bool keep_going, ReadErrors* errors, bool ignore_incorrect_picture_mx delete p; if (root == "CompositionPlaylist") { - _cpls.push_back (shared_ptr<CPL> (new CPL (path))); + shared_ptr<CPL> cpl (new CPL (path)); + if (_standard && cpl->standard() && cpl->standard().get() != _standard.get()) { + survivable_error (keep_going, errors, MismatchedStandardError ()); + } + _cpls.push_back (cpl); } else if (root == "DCSubtitle") { + if (_standard && _standard.get() == SMPTE) { + survivable_error (keep_going, errors, MismatchedStandardError ()); + } other_assets.push_back (shared_ptr<InteropSubtitleAsset> (new InteropSubtitleAsset (path))); } } else if (boost::filesystem::extension (path) == ".mxf") { + + /* XXX: asdcplib does not appear to support discovery of read MXFs standard + (Interop / SMPTE) + */ + ASDCP::EssenceType_t type; if (ASDCP::EssenceType (path.string().c_str(), type) != ASDCP::RESULT_OK) { throw DCPReadError ("Could not find essence type"); @@ -270,9 +299,9 @@ DCP::write_pkl (Standard standard, string pkl_uuid, XMLMetadata metadata, shared xmlpp::Document doc; xmlpp::Element* pkl; if (standard == INTEROP) { - pkl = doc.create_root_node("PackingList", "http://www.digicine.com/PROTO-ASDCP-PKL-20040311#"); + pkl = doc.create_root_node("PackingList", pkl_interop_ns); } else { - pkl = doc.create_root_node("PackingList", "http://www.smpte-ra.org/schemas/429-8/2007/PKL"); + pkl = doc.create_root_node("PackingList", pkl_smpte_ns); } if (signer) { @@ -325,10 +354,10 @@ DCP::write_volindex (Standard standard) const switch (standard) { case INTEROP: - root = doc.create_root_node ("VolumeIndex", "http://www.digicine.com/PROTO-ASDCP-AM-20040311#"); + root = doc.create_root_node ("VolumeIndex", volindex_interop_ns); break; case SMPTE: - root = doc.create_root_node ("VolumeIndex", "http://www.smpte-ra.org/schemas/429-9/2007/AM"); + root = doc.create_root_node ("VolumeIndex", volindex_smpte_ns); break; default: DCP_ASSERT (false); @@ -359,10 +388,10 @@ DCP::write_assetmap (Standard standard, string pkl_uuid, int pkl_length, XMLMeta switch (standard) { case INTEROP: - root = doc.create_root_node ("AssetMap", "http://www.digicine.com/PROTO-ASDCP-AM-20040311#"); + root = doc.create_root_node ("AssetMap", assetmap_interop_ns); break; case SMPTE: - root = doc.create_root_node ("AssetMap", "http://www.smpte-ra.org/schemas/429-9/2007/AM"); + root = doc.create_root_node ("AssetMap", assetmap_smpte_ns); break; default: DCP_ASSERT (false); @@ -102,6 +102,11 @@ public: void resolve_refs (std::list<boost::shared_ptr<Asset> > assets); + /** @return Standard of a DCP that was read in */ + boost::optional<Standard> standard () const { + return _standard; + } + private: /** Write the PKL file. @@ -126,6 +131,9 @@ private: boost::filesystem::path _directory; /** the CPLs that make up this DCP */ std::list<boost::shared_ptr<CPL> > _cpls; + + /** Standard of DCP that was read in */ + boost::optional<Standard> _standard; }; } diff --git a/src/exceptions.cc b/src/exceptions.cc index ed6edaa4..14ae8e9c 100644 --- a/src/exceptions.cc +++ b/src/exceptions.cc @@ -70,3 +70,9 @@ ProgrammingError::ProgrammingError (string file, int line) { } + +MismatchedStandardError::MismatchedStandardError () + : DCPReadError ("DCP contains both Interop and SMPTE parts") +{ + +} diff --git a/src/exceptions.h b/src/exceptions.h index 801bfb01..3410337e 100644 --- a/src/exceptions.h +++ b/src/exceptions.h @@ -153,6 +153,12 @@ public: ProgrammingError (std::string file, int line); }; +class MismatchedStandardError : public DCPReadError +{ +public: + MismatchedStandardError (); +}; + } #endif diff --git a/src/modified_gamma_transfer_function.h b/src/modified_gamma_transfer_function.h index e8875d4b..c200743a 100644 --- a/src/modified_gamma_transfer_function.h +++ b/src/modified_gamma_transfer_function.h @@ -25,10 +25,15 @@ namespace dcp { -/** A transfer function which for an input x gives an output y where +/** A transfer function which for an input x gives a linear output y where * * y = x / B for x <= threshold * y = ((x + A) / (1 + A))^power for x > threshold + * + * The reverse transform is + * + * x = y * B for y <= threshold / B + * x = (1 + A) * y ^ (1 / power) - A for y > threshold / B */ class ModifiedGammaTransferFunction : public TransferFunction { |
