Skip to content

Commit bfa7f62

Browse files
authored
Merge pull request #1975 from Exiv2/mergify/bp/0.27-maintenance/pr-1974
Performance boost: don't read boxes we're not interested in (backport #1974)
2 parents 1f950b0 + 07d3f7a commit bfa7f62

File tree

1 file changed

+21
-1
lines changed

1 file changed

+21
-1
lines changed

src/bmffimage.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,14 @@ namespace Exiv2
127127
return box == TAG_meta || box == TAG_iinf || box == TAG_iloc;
128128
}
129129

130+
static bool skipBox(uint32_t box)
131+
{
132+
// Allows boxHandler() to optimise the reading of files by identifying
133+
// box types that we're not interested in. Box types listed here must
134+
// not appear in the cases in switch (box_type) in boxHandler().
135+
return box == TAG_mdat; // mdat is where the main image lives and can be huge
136+
}
137+
130138
std::string BmffImage::mimeType() const
131139
{
132140
switch (fileType_) {
@@ -232,7 +240,18 @@ namespace Exiv2
232240
long restore = io_->tell();
233241
enforce(box_length >= hdrsize, Exiv2::kerCorruptedMetadata);
234242
enforce(box_length - hdrsize <= static_cast<size_t>(pbox_end - restore), Exiv2::kerCorruptedMetadata);
235-
DataBuf data(static_cast<long>(box_length - hdrsize));
243+
244+
const long buffer_size = static_cast<long>(box_length - hdrsize);
245+
if (skipBox(box_type)) {
246+
if (bTrace) {
247+
out << std::endl;
248+
}
249+
// The enforce() above checks that restore + buffer_size won't
250+
// exceed pbox_end, and by implication, won't excced LONG_MAX
251+
return restore + buffer_size;
252+
}
253+
254+
DataBuf data(buffer_size);
236255
const long box_end = restore + data.size_;
237256
io_->read(data.pData_, data.size_);
238257
io_->seek(restore, BasicIo::beg);
@@ -250,6 +269,7 @@ namespace Exiv2
250269
}
251270

252271
switch (box_type) {
272+
// See notes in skipBox()
253273
case TAG_ftyp: {
254274
enforce(data.size_ >= 4, Exiv2::kerCorruptedMetadata);
255275
fileType_ = getLong(data.pData_, endian_);

0 commit comments

Comments
 (0)