+ vector<dcp::VerificationNote> expected;
+
+ for (auto frame = 0; frame < 24; frame++) {
+ expected.push_back(
+ dcp::VerificationNote(
+ dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::INVALID_PICTURE_FRAME_SIZE_IN_BYTES, canonical(path / "video.mxf")
+ ).set_frame(frame).set_frame_rate(24).set_cpl_id(cpl->id())
+ );
+ }
+
+ int component_sizes[] = {
+ 1321816,
+ 1294414,
+ 1289881,
+ };
+
+ for (auto frame = 0; frame < 24; frame++) {
+ for (auto component = 0; component < 3; component++) {
+ expected.push_back(
+ dcp::VerificationNote(
+ dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::INVALID_JPEG2000_TILE_PART_SIZE
+ ).set_frame(frame).set_component(component).set_size(component_sizes[component]).set_cpl_id(cpl->id())
+ );
+ }
+ }
+
+ expected.push_back(
+ dcp::VerificationNote(
+ dcp::VerificationNote::Type::WARNING, dcp::VerificationNote::Code::MISSING_FFOC
+ ).set_cpl_id(cpl->id())
+ );
+
+ expected.push_back(
+ dcp::VerificationNote(
+ dcp::VerificationNote::Type::WARNING, dcp::VerificationNote::Code::MISSING_LFOC
+ ).set_cpl_id(cpl->id())
+ );
+
+ check_verify_result({ path }, {}, expected);
+}
+
+
+BOOST_AUTO_TEST_CASE(verify_too_many_subtitle_namespaces)
+{
+ boost::filesystem::path const dir = "test/ref/DCP/subtitle_namespace_test";
+ dcp::DCP dcp(dir);
+ dcp.read();
+ BOOST_REQUIRE(!dcp.cpls().empty());
+ auto cpl = dcp.cpls()[0];
+
+ check_verify_result(
+ { dir },
+ {},
+ {
+ dcp::VerificationNote(
+ dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_FFEC_IN_FEATURE
+ ).set_cpl_id(cpl->id()),
+ dcp::VerificationNote(
+ dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_FFMC_IN_FEATURE
+ ).set_cpl_id(cpl->id()),
+ dcp::VerificationNote(
+ dcp::VerificationNote::Type::WARNING, dcp::VerificationNote::Code::INVALID_SUBTITLE_FIRST_TEXT_TIME
+ ).set_cpl_id(cpl->id()),
+ dcp::VerificationNote(
+ dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_SUBTITLE_LANGUAGE, canonical(find_file(dir, "sub_"))
+ ).set_cpl_id(cpl->id()),
+ dcp::VerificationNote(
+ dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, canonical(find_file(dir, "cpl_"))
+ ).set_cpl_id(cpl->id()),
+ dcp::VerificationNote(
+ dcp::VerificationNote::Type::WARNING, dcp::VerificationNote::Code::INCORRECT_SUBTITLE_NAMESPACE_COUNT, std::string{"315de731-1173-484c-9a35-bdacf5a9d99d"}
+ ).set_cpl_id(cpl->id())
+ });
+}
+
+
+BOOST_AUTO_TEST_CASE(verify_missing_load_font_for_font)
+{
+ path const dir("build/test/verify_missing_load_font");
+ prepare_directory (dir);
+ copy_file ("test/data/subs1.xml", dir / "subs.xml");
+ {
+ Editor editor(dir / "subs.xml");
+ editor.delete_first_line_containing("LoadFont");
+ }
+ auto asset = make_shared<dcp::InteropSubtitleAsset>(dir / "subs.xml");
+ auto reel_asset = make_shared<dcp::ReelInteropSubtitleAsset>(asset, dcp::Fraction(24, 1), 16 * 24, 0);
+ auto cpl = write_dcp_with_single_asset(dir, reel_asset, dcp::Standard::INTEROP);
+
+ check_verify_result (
+ {dir},
+ {},
+ {
+ { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::INVALID_STANDARD },
+ dcp::VerificationNote(dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::MISSING_LOAD_FONT_FOR_FONT).set_id("theFontId").set_cpl_id(cpl->id())
+ });
+
+}
+
+
+BOOST_AUTO_TEST_CASE(verify_missing_load_font)
+{
+ boost::filesystem::path const dir = "build/test/verify_missing_load_font";
+ prepare_directory(dir);
+ auto dcp = make_simple (dir, 1, 202);
+
+ string const xml =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<SubtitleReel xmlns=\"http://www.smpte-ra.org/schemas/428-7/2010/DCST\">"
+ "<Id>urn:uuid:e6a8ae03-ebbf-41ed-9def-913a87d1493a</Id>"
+ "<ContentTitleText>Content</ContentTitleText>"
+ "<AnnotationText>Annotation</AnnotationText>"
+ "<IssueDate>2018-10-02T12:25:14+02:00</IssueDate>"
+ "<ReelNumber>1</ReelNumber>"
+ "<EditRate>24 1</EditRate>"
+ "<TimeCodeRate>24</TimeCodeRate>"
+ "<StartTime>00:00:00:00</StartTime>"
+ "<Language>de-DE</Language>"
+ "<SubtitleList>"
+ "<Font ID=\"arial\" Color=\"FFFEFEFE\" Weight=\"normal\" Size=\"42\" Effect=\"border\" EffectColor=\"FF181818\" AspectAdjust=\"1.00\">"
+ "<Subtitle SpotNumber=\"1\" TimeIn=\"00:00:06:00\" TimeOut=\"00:00:08:10\" FadeUpTime=\"00:00:00:00\" FadeDownTime=\"00:00:00:00\">"
+ "<Text Hposition=\"0.0\" Halign=\"center\" Valign=\"bottom\" Vposition=\"13.5\" Direction=\"ltr\">Hello world</Text>"
+ "</Subtitle>"
+ "</Font>"
+ "</SubtitleList>"
+ "</SubtitleReel>";
+
+ dcp::File xml_file(dir / "subs.xml", "w");
+ BOOST_REQUIRE(xml_file);
+ xml_file.write(xml.c_str(), xml.size(), 1);
+ xml_file.close();
+ auto subs = make_shared<dcp::SMPTESubtitleAsset>(dir / "subs.xml");
+ subs->write(dir / "subs.mxf");
+
+ auto reel_subs = make_shared<dcp::ReelSMPTESubtitleAsset>(subs, dcp::Fraction(24, 1), 202, 0);
+ auto cpl = dcp->cpls()[0];
+ cpl->reels()[0]->add(reel_subs);
+ dcp->write_xml();
+
+ check_verify_result (
+ { dir },
+ {},
+ {
+ dcp::VerificationNote(dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::MISSING_LOAD_FONT).set_id(reel_subs->id()).set_cpl_id(cpl->id())
+ });
+}
+
+
+BOOST_AUTO_TEST_CASE(verify_spots_wrong_asset)
+{
+ boost::filesystem::path const dir = "build/test/verify_spots_wrong_asset";
+ boost::filesystem::remove_all(dir);
+
+ auto dcp1 = make_simple(dir / "1");
+ dcp1->write_xml();
+
+ auto const asset_1 = dcp::MonoPictureAsset(dir / "1" / "video.mxf").id();
+
+ auto dcp2 = make_simple(dir / "2");
+ dcp2->write_xml();
+ auto const asset_2 = dcp::MonoPictureAsset(dir / "2" / "video.mxf").id();
+
+ boost::filesystem::remove(dir / "1" / "video.mxf");
+ boost::filesystem::copy_file(dir / "2" / "video.mxf", dir / "1" / "video.mxf");
+