Verify that main picture active area is valid (even, and not too big) (#2392). v1.8.40
authorCarl Hetherington <cth@carlh.net>
Thu, 15 Dec 2022 23:01:47 +0000 (00:01 +0100)
committerCarl Hetherington <cth@carlh.net>
Fri, 16 Dec 2022 09:30:26 +0000 (10:30 +0100)
src/verify.cc
src/verify.h
test/verify_test.cc

index d4d63902185d2ebed0c62c06cf842f32162e0068..197e51831ec8f7ffa85add85d9d7dd5ef55b838c 100644 (file)
@@ -1389,6 +1389,24 @@ dcp::verify (
                        size_t most_closed_captions = 0;
                        map<Marker, Time> markers_seen;
 
+                       auto const main_picture_active_area = cpl->main_picture_active_area();
+                       if (main_picture_active_area && (main_picture_active_area->width % 2)) {
+                               notes.push_back({
+                                               VerificationNote::Type::ERROR,
+                                               VerificationNote::Code::INVALID_MAIN_PICTURE_ACTIVE_AREA,
+                                               String::compose("width %1 is not a multiple of 2", main_picture_active_area->width),
+                                               cpl->file().get()
+                                       });
+                       }
+                       if (main_picture_active_area && (main_picture_active_area->height % 2)) {
+                               notes.push_back({
+                                               VerificationNote::Type::ERROR,
+                                               VerificationNote::Code::INVALID_MAIN_PICTURE_ACTIVE_AREA,
+                                               String::compose("height %1 is not a multiple of 2", main_picture_active_area->height),
+                                               cpl->file().get()
+                                       });
+                       }
+
                        for (auto reel: cpl->reels()) {
                                stage ("Checking reel", optional<boost::filesystem::path>());
 
@@ -1437,6 +1455,25 @@ dcp::verify (
                                        /* Check asset */
                                        if (reel->main_picture()->asset_ref().resolved()) {
                                                verify_main_picture_asset (dcp, reel->main_picture(), stage, progress, notes);
+                                               auto const asset_size = reel->main_picture()->asset()->size();
+                                               if (main_picture_active_area) {
+                                                       if (main_picture_active_area->width > asset_size.width) {
+                                                               notes.push_back({
+                                                                               VerificationNote::Type::ERROR,
+                                                                               VerificationNote::Code::INVALID_MAIN_PICTURE_ACTIVE_AREA,
+                                                                               String::compose("width %1 is bigger than the asset width %2", main_picture_active_area->width, asset_size.width),
+                                                                               cpl->file().get()
+                                                                               });
+                                                       }
+                                                       if (main_picture_active_area->height > asset_size.height) {
+                                                               notes.push_back({
+                                                                               VerificationNote::Type::ERROR,
+                                                                               VerificationNote::Code::INVALID_MAIN_PICTURE_ACTIVE_AREA,
+                                                                               String::compose("height %1 is bigger than the asset height %2", main_picture_active_area->height, asset_size.height),
+                                                                               cpl->file().get()
+                                                                               });
+                                                       }
+                                               }
                                        }
                                }
 
@@ -1785,6 +1822,8 @@ dcp::note_to_string (VerificationNote note)
                return "There is an <Duration> node inside a <MainMarkers>.";
        case VerificationNote::Code::INVALID_CONTENT_KIND:
                return String::compose("<ContentKind> has an invalid value %1.", note.note().get());
+       case VerificationNote::Code::INVALID_MAIN_PICTURE_ACTIVE_AREA:
+               return String::compose("<MainPictureActiveaArea> has an invalid value: %1", note.note().get());
        }
 
        return "";
index baa36138e4b7e6f446936c77ae8a2dd245c151c2..c7c4b6c8835147ad712142b7642c1ea9a5217489 100644 (file)
@@ -398,7 +398,12 @@ public:
                /** Some <MainMarkers> asset has an <Duration> that should not be there */
                UNEXPECTED_DURATION,
                /** A <ContentKind> has been specified with either no scope or the SMPTE 429-7 scope, but which is not one of those allowed */
-               INVALID_CONTENT_KIND
+               INVALID_CONTENT_KIND,
+               /** Either the width or height of a <MainPictureActiveArea> in a CPL is either not an even number, or bigger than the corresponding asset dimension.
+                *  note contains details of what is wrong
+                *  file contains the CPL filename
+                */
+               INVALID_MAIN_PICTURE_ACTIVE_AREA,
        };
 
        VerificationNote (Type type, Code code)
index 52d774bdf6c42d8a87d5113076860e199329701e..1122f73b5f550c1e66f3b94735322f0495f42503 100644 (file)
@@ -1192,8 +1192,8 @@ check_picture_size (int width, int height, int frame_rate, bool three_d)
        cpl->set_issue_date ("2012-07-17T04:45:18+00:00");
        cpl->set_main_sound_configuration ("L,C,R,Lfe,-,-");
        cpl->set_main_sound_sample_rate (48000);
-       cpl->set_main_picture_stored_area (dcp::Size(1998, 1080));
-       cpl->set_main_picture_active_area (dcp::Size(1998, 1080));
+       cpl->set_main_picture_stored_area(dcp::Size(width, height));
+       cpl->set_main_picture_active_area(dcp::Size(width, height));
        cpl->set_version_number (1);
 
        auto reel = make_shared<dcp::Reel>();
@@ -3280,3 +3280,66 @@ BOOST_AUTO_TEST_CASE(verify_valid_content_kind)
                });
 
 }
+
+
+BOOST_AUTO_TEST_CASE(verify_invalid_main_picture_active_area_1)
+{
+       path dir = "build/test/verify_invalid_main_picture_active_area_1";
+       prepare_directory(dir);
+       auto dcp = make_simple(dir, 1, 24);
+       dcp->write_xml();
+
+       auto constexpr area = "<meta:MainPictureActiveArea>";
+
+       {
+               Editor e(find_cpl(dir));
+               e.delete_lines_after(area, 2);
+               e.insert(area, "<meta:Height>4080</meta:Height>");
+               e.insert(area, "<meta:Width>1997</meta:Width>");
+       }
+
+       dcp::PKL pkl(find_pkl(dir));
+       dcp::CPL cpl(find_cpl(dir));
+
+       check_verify_result(
+               { dir },
+               {
+                       { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::MISMATCHED_CPL_HASHES, cpl.id(), canonical(find_cpl(dir)) },
+                       { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISMATCHED_PKL_ANNOTATION_TEXT_WITH_CPL, pkl.id(), canonical(find_pkl(dir)), },
+                       { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::INVALID_MAIN_PICTURE_ACTIVE_AREA, "width 1997 is not a multiple of 2", canonical(find_cpl(dir)) },
+                       { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::INVALID_MAIN_PICTURE_ACTIVE_AREA, "height 4080 is bigger than the asset height 1080", canonical(find_cpl(dir)) },
+               });
+}
+
+
+BOOST_AUTO_TEST_CASE(verify_invalid_main_picture_active_area_2)
+{
+       path dir = "build/test/verify_invalid_main_picture_active_area_2";
+       prepare_directory(dir);
+       auto dcp = make_simple(dir, 1, 24);
+       dcp->write_xml();
+
+       auto constexpr area = "<meta:MainPictureActiveArea>";
+
+       {
+               Editor e(find_cpl(dir));
+               e.delete_lines_after(area, 2);
+               e.insert(area, "<meta:Height>5125</meta:Height>");
+               e.insert(area, "<meta:Width>9900</meta:Width>");
+       }
+
+       dcp::PKL pkl(find_pkl(dir));
+       dcp::CPL cpl(find_cpl(dir));
+
+       check_verify_result(
+               { dir },
+               {
+                       { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::MISMATCHED_CPL_HASHES, cpl.id(), canonical(find_cpl(dir)) },
+                       { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISMATCHED_PKL_ANNOTATION_TEXT_WITH_CPL, pkl.id(), canonical(find_pkl(dir)), },
+                       { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::INVALID_MAIN_PICTURE_ACTIVE_AREA, "height 5125 is not a multiple of 2", canonical(find_cpl(dir)) },
+                       { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::INVALID_MAIN_PICTURE_ACTIVE_AREA, "width 9900 is bigger than the asset width 1998", canonical(find_cpl(dir)) },
+                       { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::INVALID_MAIN_PICTURE_ACTIVE_AREA, "height 5125 is bigger than the asset height 1080", canonical(find_cpl(dir)) },
+               });
+}
+
+