Skip to content

Commit b565b3e

Browse files
committed
MP4: Support reading any size flag atom
1 parent 06618cf commit b565b3e

File tree

2 files changed

+25
-14
lines changed

2 files changed

+25
-14
lines changed

lofty/src/mp4/ilst/read.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -120,10 +120,9 @@ where
120120
parse_data_inner(&mut ilst_reader, parsing_mode, &atom)?
121121
{
122122
if let Some((_, content)) = atom_data.first() {
123-
let data = match content[..] {
124-
[0, ..] => AtomData::Bool(false),
125-
_ => AtomData::Bool(true),
126-
};
123+
// Any size integer is technically valid, we'll correct it on write.
124+
let is_true = content.iter().any(|&b| b != 0);
125+
let data = AtomData::Bool(is_true);
127126

128127
tag.atoms.push(Atom {
129128
ident: AtomIdent::Fourcc(*fourcc),

lofty/src/mp4/ilst/write.rs

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ use crate::util::io::{FileLike, Length, Truncate};
1414

1515
use std::io::{Cursor, Seek, SeekFrom, Write};
1616

17+
use crate::mp4::constants::{
18+
BE_SIGNED_INTEGER, BE_UNSIGNED_INTEGER, BMP, JPEG, PNG, RESERVED, UTF16, UTF8,
19+
};
1720
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
1821

1922
// A "full" atom is a traditional length + identifier, followed by a version (1) and flags (3)
@@ -675,12 +678,12 @@ where
675678
{
676679
for value in data {
677680
match value {
678-
AtomData::UTF8(text) => write_data(1, text.as_bytes(), writer)?,
679-
AtomData::UTF16(text) => write_data(2, text.as_bytes(), writer)?,
681+
AtomData::UTF8(text) => write_data(UTF8, text.as_bytes(), writer)?,
682+
AtomData::UTF16(text) => write_data(UTF16, text.as_bytes(), writer)?,
680683
AtomData::Picture(ref pic) => write_picture(pic, writer)?,
681684
AtomData::SignedInteger(int) => write_signed_int(*int, writer)?,
682685
AtomData::UnsignedInteger(uint) => write_unsigned_int(*uint, writer)?,
683-
AtomData::Bool(b) => write_signed_int(i32::from(*b), writer)?,
686+
AtomData::Bool(b) => write_bool(*b, writer)?,
684687
AtomData::Unknown { code, ref data } => write_data(*code, data, writer)?,
685688
};
686689
}
@@ -689,7 +692,7 @@ where
689692
}
690693

691694
fn write_signed_int(int: i32, writer: &mut AtomWriterCompanion<'_>) -> Result<()> {
692-
write_int(21, int.to_be_bytes(), 4, writer)
695+
write_int(BE_SIGNED_INTEGER, int.to_be_bytes(), 4, writer)
693696
}
694697

695698
fn bytes_to_occupy_uint(uint: u32) -> usize {
@@ -706,7 +709,12 @@ fn bytes_to_occupy_uint(uint: u32) -> usize {
706709

707710
fn write_unsigned_int(uint: u32, writer: &mut AtomWriterCompanion<'_>) -> Result<()> {
708711
let bytes_needed = bytes_to_occupy_uint(uint);
709-
write_int(22, uint.to_be_bytes(), bytes_needed, writer)
712+
write_int(
713+
BE_UNSIGNED_INTEGER,
714+
uint.to_be_bytes(),
715+
bytes_needed,
716+
writer,
717+
)
710718
}
711719

712720
fn write_int(
@@ -719,15 +727,19 @@ fn write_int(
719727
write_data(flags, &bytes[4 - bytes_needed..], writer)
720728
}
721729

730+
fn write_bool(b: bool, writer: &mut AtomWriterCompanion<'_>) -> Result<()> {
731+
write_int(BE_SIGNED_INTEGER, i32::from(b).to_be_bytes(), 1, writer)
732+
}
733+
722734
fn write_picture(picture: &Picture, writer: &mut AtomWriterCompanion<'_>) -> Result<()> {
723735
match picture.mime_type {
724736
// GIF is deprecated
725737
Some(MimeType::Gif) => write_data(12, &picture.data, writer),
726-
Some(MimeType::Jpeg) => write_data(13, &picture.data, writer),
727-
Some(MimeType::Png) => write_data(14, &picture.data, writer),
728-
Some(MimeType::Bmp) => write_data(27, &picture.data, writer),
738+
Some(MimeType::Jpeg) => write_data(JPEG, &picture.data, writer),
739+
Some(MimeType::Png) => write_data(PNG, &picture.data, writer),
740+
Some(MimeType::Bmp) => write_data(BMP, &picture.data, writer),
729741
// We'll assume implicit (0) was the intended type
730-
None => write_data(0, &picture.data, writer),
742+
None => write_data(RESERVED, &picture.data, writer),
731743
_ => Err(FileEncodingError::new(
732744
FileType::Mp4,
733745
"Attempted to write an unsupported picture format",
@@ -766,7 +778,7 @@ fn write_data(flags: u32, data: &[u8], writer: &mut AtomWriterCompanion<'_>) ->
766778

767779
#[cfg(test)]
768780
mod tests {
769-
use crate::mp4::ilst::write::bytes_to_occupy_uint;
781+
use super::bytes_to_occupy_uint;
770782

771783
macro_rules! int_test {
772784
(

0 commit comments

Comments
 (0)