Skip to content

Commit 2785cb3

Browse files
committed
Read all relevant items
1 parent cbb89fc commit 2785cb3

File tree

1 file changed

+30
-29
lines changed

1 file changed

+30
-29
lines changed

mp4parse/src/lib.rs

Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1257,26 +1257,41 @@ pub fn read_avif<T: Read>(f: &mut T, context: &mut AvifContext) -> Result<()> {
12571257
}
12581258

12591259
let meta = meta.ok_or(Error::InvalidData("missing meta"))?;
1260-
let primary_item_loc = get_primary_item_loc(&meta)?;
1261-
if primary_item_loc.construction_method != ConstructionMethod::File {
1262-
return Err(Error::Unsupported("unsupported construction_method"));
1263-
}
12641260

1265-
let mut primary_item = TryVec::new();
1266-
for extent in primary_item_loc.extents.iter() {
1267-
// try to find an overlapping mdat
1268-
for mdat in mdats.iter_mut() {
1269-
if mdat.matches_extent(&extent.extent_range) {
1270-
primary_item.append(&mut mdat.data)?;
1271-
break;
1272-
} else if mdat.contains_extent(&extent.extent_range) {
1273-
mdat.read_extent(&extent.extent_range, &mut primary_item)?;
1274-
break;
1261+
// load data of relevant items
1262+
for loc in meta.iloc_items.iter() {
1263+
if loc.item_id != meta.primary_item_id {
1264+
continue;
1265+
}
1266+
1267+
if loc.construction_method != ConstructionMethod::File {
1268+
return Err(Error::Unsupported("unsupported construction_method"));
1269+
}
1270+
let mut item_data = TryVec::new();
1271+
for extent in loc.extents.iter() {
1272+
let mut found = false;
1273+
// try to find an overlapping mdat
1274+
for mdat in mdats.iter_mut() {
1275+
if mdat.matches_extent(&extent.extent_range) {
1276+
item_data.append(&mut mdat.data)?;
1277+
found = true;
1278+
break;
1279+
} else if mdat.contains_extent(&extent.extent_range) {
1280+
mdat.read_extent(&extent.extent_range, &mut item_data)?;
1281+
found = true;
1282+
break;
1283+
}
1284+
}
1285+
if !found {
1286+
return Err(Error::InvalidData("iloc contains an extent that is not in mdat"));
12751287
}
12761288
}
1289+
1290+
if loc.item_id == meta.primary_item_id {
1291+
context.primary_item = item_data;
1292+
}
12771293
}
12781294

1279-
context.primary_item = primary_item;
12801295
Ok(())
12811296
}
12821297

@@ -1359,20 +1374,6 @@ fn read_avif_meta<T: Read + Offset>(src: &mut BMFFBox<T>) -> Result<AvifMeta> {
13591374
})
13601375
}
13611376

1362-
fn get_primary_item_loc(meta: &AvifMeta) -> Result<&ItemLocationBoxItem> {
1363-
if let Some(loc) = meta
1364-
.iloc_items
1365-
.iter()
1366-
.find(|loc| loc.item_id == meta.primary_item_id)
1367-
{
1368-
Ok(loc)
1369-
} else {
1370-
Err(Error::InvalidData(
1371-
"primary_item_id not present in iloc box",
1372-
))
1373-
}
1374-
}
1375-
13761377
/// Parse a Primary Item Box
13771378
/// See ISO 14496-12:2015 § 8.11.4
13781379
fn read_pitm<T: Read>(src: &mut BMFFBox<T>) -> Result<u32> {

0 commit comments

Comments
 (0)