Allow use of KDMs when verifying DCPs.
[libdcp.git] / src / verify.cc
index 42ee192119b85280ada83512167a01aaa2a4805d..960f0438816a3c726a604ecdcf692ac79fa5f4c5 100644 (file)
@@ -41,6 +41,7 @@
 #include "cpl.h"
 #include "dcp.h"
 #include "exceptions.h"
+#include "filesystem.h"
 #include "interop_subtitle_asset.h"
 #include "mono_picture_asset.h"
 #include "mono_picture_frame.h"
@@ -392,7 +393,9 @@ verify_asset (shared_ptr<const DCP> dcp, shared_ptr<const ReelFileAsset> reel_fi
         * call to hash().
         */
        reel_file_asset->asset_ref()->unset_hash();
-       auto const actual_hash = reel_file_asset->asset_ref()->hash(progress);
+       auto const actual_hash = reel_file_asset->asset_ref()->hash([progress](int64_t done, int64_t total) {
+               progress(float(done) / total);
+       });
 
        auto pkls = dcp->pkls();
        /* We've read this DCP in so it must have at least one PKL */
@@ -504,7 +507,7 @@ verify_main_picture_asset (
        auto asset = reel_asset->asset();
        auto const file = *asset->file();
 
-       if (options.check_asset_hashes && (!options.maximum_asset_size_for_hash_check || boost::filesystem::file_size(file) < *options.maximum_asset_size_for_hash_check)) {
+       if (options.check_asset_hashes && (!options.maximum_asset_size_for_hash_check || filesystem::file_size(file) < *options.maximum_asset_size_for_hash_check)) {
                stage ("Checking picture asset hash", file);
                auto const r = verify_asset (dcp, reel_asset, progress);
                switch (r) {
@@ -600,7 +603,7 @@ verify_main_sound_asset (
        auto asset = reel_asset->asset();
        auto const file = *asset->file();
 
-       if (options.check_asset_hashes && (!options.maximum_asset_size_for_hash_check || boost::filesystem::file_size(file) < *options.maximum_asset_size_for_hash_check)) {
+       if (options.check_asset_hashes && (!options.maximum_asset_size_for_hash_check || filesystem::file_size(file) < *options.maximum_asset_size_for_hash_check)) {
                stage("Checking sound asset hash", file);
                auto const r = verify_asset (dcp, reel_asset, progress);
                switch (r) {
@@ -678,7 +681,7 @@ verify_smpte_timed_text_asset (
                notes.push_back ({ VerificationNote::Type::BV21_ERROR, VerificationNote::Code::MISSING_SUBTITLE_LANGUAGE, *asset->file() });
        }
 
-       auto const size = boost::filesystem::file_size(asset->file().get());
+       auto const size = filesystem::file_size(asset->file().get());
        if (size > 115 * 1024 * 1024) {
                notes.push_back (
                        { VerificationNote::Type::BV21_ERROR, VerificationNote::Code::INVALID_TIMED_TEXT_SIZE_IN_BYTES, raw_convert<string>(size), *asset->file() }
@@ -715,9 +718,9 @@ verify_smpte_timed_text_asset (
 }
 
 
-/** Verify Interop subtitle-only stuff */
+/** Verify Interop subtitle / CCAP stuff */
 void
-verify_interop_subtitle_asset(shared_ptr<const InteropSubtitleAsset> asset, vector<VerificationNote>& notes)
+verify_interop_text_asset(shared_ptr<const InteropSubtitleAsset> asset, vector<VerificationNote>& notes)
 {
        if (asset->subtitles().empty()) {
                notes.push_back({VerificationNote::Type::ERROR, VerificationNote::Code::MISSING_SUBTITLE, asset->id(), asset->file().get() });
@@ -806,7 +809,7 @@ verify_subtitle_asset (
 
        auto interop = dynamic_pointer_cast<const InteropSubtitleAsset>(asset);
        if (interop) {
-               verify_interop_subtitle_asset(interop, notes);
+               verify_interop_text_asset(interop, notes);
                if (namespace_count(asset, "DCSubtitle") > 1) {
                        notes.push_back({ VerificationNote::Type::WARNING, VerificationNote::Code::INCORRECT_SUBTITLE_NAMESPACE_COUNT, asset->id() });
                }
@@ -848,6 +851,11 @@ verify_closed_caption_asset (
                notes.push_back ({VerificationNote::Type::WARNING, VerificationNote::Code::MISSED_CHECK_OF_ENCRYPTED});
        }
 
+       auto interop = dynamic_pointer_cast<const InteropSubtitleAsset>(asset);
+       if (interop) {
+               verify_interop_text_asset(interop, notes);
+       }
+
        auto smpte = dynamic_pointer_cast<const SMPTESubtitleAsset>(asset);
        if (smpte) {
                verify_smpte_timed_text_asset (smpte, reel_asset_duration, notes);
@@ -1292,7 +1300,7 @@ verify_extension_metadata(shared_ptr<const CPL> cpl, vector<VerificationNote>& n
 {
        DCP_ASSERT (cpl->file());
        cxml::Document doc ("CompositionPlaylist");
-       doc.read_file (cpl->file().get());
+       doc.read_file(dcp::filesystem::fix_long_path(cpl->file().get()));
 
        auto missing = false;
        string malformed;
@@ -1734,7 +1742,7 @@ verify_cpl(
                if (cpl->any_encrypted()) {
                        cxml::Document doc("CompositionPlaylist");
                        DCP_ASSERT(cpl->file());
-                       doc.read_file(cpl->file().get());
+                       doc.read_file(dcp::filesystem::fix_long_path(cpl->file().get()));
                        if (!doc.optional_node_child("Signature")) {
                                notes.push_back({VerificationNote::Type::BV21_ERROR, VerificationNote::Code::UNSIGNED_CPL_WITH_ENCRYPTED_CONTENT, cpl->id(), cpl->file().get()});
                        }
@@ -1756,7 +1764,7 @@ verify_pkl(
 
        if (pkl_has_encrypted_assets(dcp, pkl)) {
                cxml::Document doc("PackingList");
-               doc.read_file(pkl->file().get());
+               doc.read_file(dcp::filesystem::fix_long_path(pkl->file().get()));
                if (!doc.optional_node_child("Signature")) {
                        notes.push_back({VerificationNote::Type::BV21_ERROR, VerificationNote::Code::UNSIGNED_PKL_WITH_ENCRYPTED_CONTENT, pkl->id(), pkl->file().get()});
                }
@@ -1799,6 +1807,7 @@ verify_assetmap(
 vector<VerificationNote>
 dcp::verify (
        vector<boost::filesystem::path> directories,
+       vector<dcp::DecryptedKDM> kdms,
        function<void (string, optional<boost::filesystem::path>)> stage,
        function<void (float)> progress,
        VerificationOptions options,
@@ -1808,7 +1817,7 @@ dcp::verify (
        if (!xsd_dtd_directory) {
                xsd_dtd_directory = resources_directory() / "xsd";
        }
-       *xsd_dtd_directory = boost::filesystem::canonical (*xsd_dtd_directory);
+       *xsd_dtd_directory = filesystem::canonical(*xsd_dtd_directory);
 
        vector<VerificationNote> notes;
        State state{};
@@ -1846,6 +1855,10 @@ dcp::verify (
                        notes.push_back ({VerificationNote::Type::BV21_ERROR, VerificationNote::Code::INVALID_STANDARD});
                }
 
+               for (auto kdm: kdms) {
+                       dcp->add(kdm);
+               }
+
                for (auto cpl: dcp->cpls()) {
                        verify_cpl(
                                dcp,