|
|
|
@ -538,8 +538,11 @@ namespace Exiv2 {
|
|
|
|
|
|
|
|
|
|
using namespace Exiv2::Internal;
|
|
|
|
|
|
|
|
|
|
QuickTimeVideo::QuickTimeVideo(BasicIo::UniquePtr io) :
|
|
|
|
|
Image(ImageType::qtime, mdNone, std::move(io)), timeScale_(1), currentStream_(Null) {
|
|
|
|
|
QuickTimeVideo::QuickTimeVideo(BasicIo::UniquePtr io, size_t max_recursion_depth) :
|
|
|
|
|
Image(ImageType::qtime, mdNone, std::move(io)),
|
|
|
|
|
timeScale_(1),
|
|
|
|
|
currentStream_(Null),
|
|
|
|
|
max_recursion_depth_(max_recursion_depth) {
|
|
|
|
|
} // QuickTimeVideo::QuickTimeVideo
|
|
|
|
|
|
|
|
|
|
std::string QuickTimeVideo::mimeType() const {
|
|
|
|
@ -569,12 +572,14 @@ void QuickTimeVideo::readMetadata() {
|
|
|
|
|
xmpData_["Xmp.video.MimeType"] = mimeType();
|
|
|
|
|
|
|
|
|
|
while (continueTraversing_)
|
|
|
|
|
decodeBlock();
|
|
|
|
|
decodeBlock(0);
|
|
|
|
|
|
|
|
|
|
xmpData_["Xmp.video.AspectRatio"] = getAspectRatio(width_, height_);
|
|
|
|
|
} // QuickTimeVideo::readMetadata
|
|
|
|
|
|
|
|
|
|
void QuickTimeVideo::decodeBlock(std::string const& entered_from) {
|
|
|
|
|
void QuickTimeVideo::decodeBlock(size_t recursion_depth, std::string const& entered_from) {
|
|
|
|
|
enforce(recursion_depth < max_recursion_depth_, Exiv2::ErrorCode::kerCorruptedMetadata);
|
|
|
|
|
|
|
|
|
|
const long bufMinSize = 4;
|
|
|
|
|
DataBuf buf(bufMinSize + 1);
|
|
|
|
|
uint64_t size = 0;
|
|
|
|
@ -613,7 +618,7 @@ void QuickTimeVideo::decodeBlock(std::string const& entered_from) {
|
|
|
|
|
if (newsize > buf.size()) {
|
|
|
|
|
buf.resize(newsize);
|
|
|
|
|
}
|
|
|
|
|
tagDecoder(buf, newsize);
|
|
|
|
|
tagDecoder(buf, newsize, recursion_depth + 1);
|
|
|
|
|
} // QuickTimeVideo::decodeBlock
|
|
|
|
|
|
|
|
|
|
static std::string readString(BasicIo& io, size_t size) {
|
|
|
|
@ -624,14 +629,15 @@ static std::string readString(BasicIo& io, size_t size) {
|
|
|
|
|
return Exiv2::toString(str.data());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void QuickTimeVideo::tagDecoder(Exiv2::DataBuf& buf, size_t size) {
|
|
|
|
|
void QuickTimeVideo::tagDecoder(Exiv2::DataBuf& buf, size_t size, size_t recursion_depth) {
|
|
|
|
|
enforce(recursion_depth < max_recursion_depth_, Exiv2::ErrorCode::kerCorruptedMetadata);
|
|
|
|
|
assert(buf.size() > 4);
|
|
|
|
|
|
|
|
|
|
if (ignoreList(buf))
|
|
|
|
|
discard(size);
|
|
|
|
|
|
|
|
|
|
else if (dataIgnoreList(buf)) {
|
|
|
|
|
decodeBlock(Exiv2::toString(buf.data()));
|
|
|
|
|
decodeBlock(recursion_depth + 1, Exiv2::toString(buf.data()));
|
|
|
|
|
} else if (equalsQTimeTag(buf, "ftyp"))
|
|
|
|
|
fileTypeDecoder(size);
|
|
|
|
|
|
|
|
|
@ -654,10 +660,10 @@ void QuickTimeVideo::tagDecoder(Exiv2::DataBuf& buf, size_t size) {
|
|
|
|
|
videoHeaderDecoder(size);
|
|
|
|
|
|
|
|
|
|
else if (equalsQTimeTag(buf, "udta"))
|
|
|
|
|
userDataDecoder(size);
|
|
|
|
|
userDataDecoder(size, recursion_depth + 1);
|
|
|
|
|
|
|
|
|
|
else if (equalsQTimeTag(buf, "dref"))
|
|
|
|
|
multipleEntriesDecoder();
|
|
|
|
|
multipleEntriesDecoder(recursion_depth + 1);
|
|
|
|
|
|
|
|
|
|
else if (equalsQTimeTag(buf, "stsd"))
|
|
|
|
|
sampleDesc(size);
|
|
|
|
@ -836,7 +842,8 @@ void QuickTimeVideo::CameraTagsDecoder(size_t size_external) {
|
|
|
|
|
io_->seek(cur_pos + size_external, BasicIo::beg);
|
|
|
|
|
} // QuickTimeVideo::CameraTagsDecoder
|
|
|
|
|
|
|
|
|
|
void QuickTimeVideo::userDataDecoder(size_t size_external) {
|
|
|
|
|
void QuickTimeVideo::userDataDecoder(size_t size_external, size_t recursion_depth) {
|
|
|
|
|
enforce(recursion_depth < max_recursion_depth_, Exiv2::ErrorCode::kerCorruptedMetadata);
|
|
|
|
|
size_t cur_pos = io_->tell();
|
|
|
|
|
const TagVocabulary* td;
|
|
|
|
|
const TagVocabulary* tv;
|
|
|
|
@ -866,7 +873,7 @@ void QuickTimeVideo::userDataDecoder(size_t size_external) {
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
if (equalsQTimeTag(buf, "DcMD") || equalsQTimeTag(buf, "NCDT"))
|
|
|
|
|
userDataDecoder(size - 8);
|
|
|
|
|
userDataDecoder(size - 8, recursion_depth + 1);
|
|
|
|
|
|
|
|
|
|
else if (equalsQTimeTag(buf, "NCTG"))
|
|
|
|
|
NikonTagsDecoder(size - 8);
|
|
|
|
@ -898,7 +905,7 @@ void QuickTimeVideo::userDataDecoder(size_t size_external) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
else if (td)
|
|
|
|
|
tagDecoder(buf, size - 8);
|
|
|
|
|
tagDecoder(buf, size - 8, recursion_depth + 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
io_->seek(cur_pos + size_external, BasicIo::beg);
|
|
|
|
@ -1272,7 +1279,8 @@ void QuickTimeVideo::imageDescDecoder() {
|
|
|
|
|
xmpData_["Xmp.video.BitDepth"] = static_cast<int>(buf.read_uint8(0));
|
|
|
|
|
} // QuickTimeVideo::imageDescDecoder
|
|
|
|
|
|
|
|
|
|
void QuickTimeVideo::multipleEntriesDecoder() {
|
|
|
|
|
void QuickTimeVideo::multipleEntriesDecoder(size_t recursion_depth) {
|
|
|
|
|
enforce(recursion_depth < max_recursion_depth_, Exiv2::ErrorCode::kerCorruptedMetadata);
|
|
|
|
|
DataBuf buf(4 + 1);
|
|
|
|
|
io_->readOrThrow(buf.data(), 4);
|
|
|
|
|
io_->readOrThrow(buf.data(), 4);
|
|
|
|
@ -1281,7 +1289,7 @@ void QuickTimeVideo::multipleEntriesDecoder() {
|
|
|
|
|
noOfEntries = buf.read_uint32(0, bigEndian);
|
|
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < noOfEntries && continueTraversing_; i++) {
|
|
|
|
|
decodeBlock();
|
|
|
|
|
decodeBlock(recursion_depth + 1);
|
|
|
|
|
}
|
|
|
|
|
} // QuickTimeVideo::multipleEntriesDecoder
|
|
|
|
|
|
|
|
|
|