summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/verify.cc11
-rw-r--r--src/verify.h44
-rw-r--r--src/verify_j2k.cc16
-rw-r--r--src/verify_j2k.h6
4 files changed, 66 insertions, 11 deletions
diff --git a/src/verify.cc b/src/verify.cc
index d43c7ff1..81ca0bc9 100644
--- a/src/verify.cc
+++ b/src/verify.cc
@@ -449,7 +449,7 @@ verify_picture_asset (shared_ptr<const ReelFileAsset> reel_file_asset, boost::fi
biggest_frame = max(biggest_frame, frame->size());
if (!mono_asset->encrypted() || mono_asset->key()) {
vector<VerificationNote> j2k_notes;
- verify_j2k (frame, j2k_notes);
+ verify_j2k(frame, i, mono_asset->frame_rate().numerator, j2k_notes);
check_and_add (j2k_notes);
}
progress (float(i) / duration);
@@ -461,8 +461,8 @@ verify_picture_asset (shared_ptr<const ReelFileAsset> reel_file_asset, boost::fi
biggest_frame = max(biggest_frame, max(frame->left()->size(), frame->right()->size()));
if (!stereo_asset->encrypted() || stereo_asset->key()) {
vector<VerificationNote> j2k_notes;
- verify_j2k (frame->left(), j2k_notes);
- verify_j2k (frame->right(), j2k_notes);
+ verify_j2k(frame->left(), i, stereo_asset->frame_rate().numerator, j2k_notes);
+ verify_j2k(frame->right(), i, stereo_asset->frame_rate().numerator, j2k_notes);
check_and_add (j2k_notes);
}
progress (float(i) / duration);
@@ -2014,6 +2014,11 @@ dcp::note_to_string (VerificationNote note)
return String::compose("<MainSoundConfiguration> has an invalid value: %1", note.note().get());
case VerificationNote::Code::MISSING_FONT:
return String::compose("The font file for font ID \"%1\" was not found, or was not referred to in the ASSETMAP.", note.note().get());
+ case VerificationNote::Code::INVALID_JPEG2000_TILE_PART_SIZE:
+ return String::compose(
+ "Frame %1 has an image component that is too large (component %2 is %3 bytes in size).",
+ note.frame().get(), note.component().get(), note.size().get()
+ );
}
return "";
diff --git a/src/verify.h b/src/verify.h
index 8eec9749..4d65fae7 100644
--- a/src/verify.h
+++ b/src/verify.h
@@ -436,7 +436,13 @@ public:
/** An interop subtitle file has a <LoadFont> node which refers to a font file that is not found.
* note contains the <LoadFont> ID
*/
- MISSING_FONT
+ MISSING_FONT,
+ /** A tile part in a JPEG2000 frame is too big.
+ * frame contains the frame index (counted from 0)
+ * component contains the component index (0, 1 or 2)
+ * size contains the invalid size in bytes.
+ */
+ INVALID_JPEG2000_TILE_PART_SIZE,
};
VerificationNote (Type type, Code code)
@@ -485,9 +491,12 @@ public:
private:
enum class Data {
- NOTE, ///< further information about the error
- FILE, ///< path of file containing the error
- LINE ///< error line number within the FILE
+ NOTE, ///< further information about the error
+ FILE, ///< path of file containing the error
+ LINE, ///< error line number within the FILE
+ FRAME,
+ COMPONENT,
+ SIZE,
};
template <class T>
@@ -513,6 +522,33 @@ public:
return data<uint64_t>(Data::LINE);
}
+ VerificationNote& set_frame(int frame) {
+ _data[Data::FRAME] = frame;
+ return *this;
+ }
+
+ boost::optional<int> frame() const {
+ return data<int>(Data::FRAME);
+ }
+
+ VerificationNote& set_component(int component) {
+ _data[Data::COMPONENT] = component;
+ return *this;
+ }
+
+ boost::optional<int> component() const {
+ return data<int>(Data::COMPONENT);
+ }
+
+ VerificationNote& set_size(int size) {
+ _data[Data::SIZE] = size;
+ return *this;
+ }
+
+ boost::optional<int> size() const {
+ return data<int>(Data::SIZE);
+ }
+
private:
Type _type;
Code _code;
diff --git a/src/verify_j2k.cc b/src/verify_j2k.cc
index 86ffb5b4..b9158849 100644
--- a/src/verify_j2k.cc
+++ b/src/verify_j2k.cc
@@ -65,8 +65,11 @@ public:
void
-dcp::verify_j2k (shared_ptr<const Data> j2k, vector<VerificationNote>& notes)
+dcp::verify_j2k(shared_ptr<const Data> j2k, int frame_index, int frame_rate, vector<VerificationNote>& notes)
{
+ /* See ITU-T T800 (visible on https://github.com/Ymagis/ClairMeta/issues/130) */
+ unsigned int const max_tile_part_size = std::floor(200e6 / (8 * frame_rate));
+
try {
auto ptr = j2k->data();
auto end = ptr + j2k->size();
@@ -202,8 +205,8 @@ dcp::verify_j2k (shared_ptr<const Data> j2k, vector<VerificationNote>& notes)
} else if (*marker_name == "SOT") {
require_16(10, "invalid SOT size %1");
get_16(); // tile index
- get_32(); // tile part length
- get_8(); // tile part index
+ auto const tile_part_length = get_32();
+ auto const tile_part_index = get_8();
auto tile_parts = get_8();
if (!fourk && tile_parts != 3) {
notes.push_back ({ VerificationNote::Type::BV21_ERROR, VerificationNote::Code::INVALID_JPEG2000_TILE_PARTS_FOR_2K, raw_convert<string>(tile_parts) });
@@ -211,6 +214,13 @@ dcp::verify_j2k (shared_ptr<const Data> j2k, vector<VerificationNote>& notes)
if (fourk && tile_parts != 6) {
notes.push_back ({ VerificationNote::Type::BV21_ERROR, VerificationNote::Code::INVALID_JPEG2000_TILE_PARTS_FOR_4K, raw_convert<string>(tile_parts) });
}
+ if (tile_part_length > max_tile_part_size) {
+ VerificationNote note{VerificationNote::Type::ERROR, VerificationNote::Code::INVALID_JPEG2000_TILE_PART_SIZE};
+ note.set_frame(frame_index);
+ note.set_component(tile_part_index);
+ note.set_size(tile_part_length);
+ notes.push_back(note);
+ }
main_header_finished = true;
} else if (*marker_name == "SOD") {
while (ptr < (end - 1) && (ptr[0] != 0xff || ptr[1] < 0x90)) {
diff --git a/src/verify_j2k.h b/src/verify_j2k.h
index 3d9093dd..ac69155c 100644
--- a/src/verify_j2k.h
+++ b/src/verify_j2k.h
@@ -51,7 +51,11 @@ namespace dcp {
class Data;
-void verify_j2k (std::shared_ptr<const Data> data, std::vector<VerificationNote>& notes);
+/** @param frame_index Video frame index, so that notes can say which frame contains the problem.
+ * @param frame_rate Video frame rate (in frames per second) to calculate how big the tile parts
+ * can be.
+ */
+void verify_j2k(std::shared_ptr<const Data> data, int frame_index, int frame_rate, std::vector<VerificationNote>& notes);
}