mirror of
https://github.com/Serial-ATA/lofty-rs
synced 2024-11-14 00:17:07 +00:00
MP4: Support reading any size flag atom
This commit is contained in:
parent
06618cf1a7
commit
b565b3e288
2 changed files with 25 additions and 14 deletions
|
@ -120,10 +120,9 @@ where
|
||||||
parse_data_inner(&mut ilst_reader, parsing_mode, &atom)?
|
parse_data_inner(&mut ilst_reader, parsing_mode, &atom)?
|
||||||
{
|
{
|
||||||
if let Some((_, content)) = atom_data.first() {
|
if let Some((_, content)) = atom_data.first() {
|
||||||
let data = match content[..] {
|
// Any size integer is technically valid, we'll correct it on write.
|
||||||
[0, ..] => AtomData::Bool(false),
|
let is_true = content.iter().any(|&b| b != 0);
|
||||||
_ => AtomData::Bool(true),
|
let data = AtomData::Bool(is_true);
|
||||||
};
|
|
||||||
|
|
||||||
tag.atoms.push(Atom {
|
tag.atoms.push(Atom {
|
||||||
ident: AtomIdent::Fourcc(*fourcc),
|
ident: AtomIdent::Fourcc(*fourcc),
|
||||||
|
|
|
@ -14,6 +14,9 @@ use crate::util::io::{FileLike, Length, Truncate};
|
||||||
|
|
||||||
use std::io::{Cursor, Seek, SeekFrom, Write};
|
use std::io::{Cursor, Seek, SeekFrom, Write};
|
||||||
|
|
||||||
|
use crate::mp4::constants::{
|
||||||
|
BE_SIGNED_INTEGER, BE_UNSIGNED_INTEGER, BMP, JPEG, PNG, RESERVED, UTF16, UTF8,
|
||||||
|
};
|
||||||
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
|
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
|
||||||
|
|
||||||
// A "full" atom is a traditional length + identifier, followed by a version (1) and flags (3)
|
// A "full" atom is a traditional length + identifier, followed by a version (1) and flags (3)
|
||||||
|
@ -675,12 +678,12 @@ where
|
||||||
{
|
{
|
||||||
for value in data {
|
for value in data {
|
||||||
match value {
|
match value {
|
||||||
AtomData::UTF8(text) => write_data(1, text.as_bytes(), writer)?,
|
AtomData::UTF8(text) => write_data(UTF8, text.as_bytes(), writer)?,
|
||||||
AtomData::UTF16(text) => write_data(2, text.as_bytes(), writer)?,
|
AtomData::UTF16(text) => write_data(UTF16, text.as_bytes(), writer)?,
|
||||||
AtomData::Picture(ref pic) => write_picture(pic, writer)?,
|
AtomData::Picture(ref pic) => write_picture(pic, writer)?,
|
||||||
AtomData::SignedInteger(int) => write_signed_int(*int, writer)?,
|
AtomData::SignedInteger(int) => write_signed_int(*int, writer)?,
|
||||||
AtomData::UnsignedInteger(uint) => write_unsigned_int(*uint, writer)?,
|
AtomData::UnsignedInteger(uint) => write_unsigned_int(*uint, writer)?,
|
||||||
AtomData::Bool(b) => write_signed_int(i32::from(*b), writer)?,
|
AtomData::Bool(b) => write_bool(*b, writer)?,
|
||||||
AtomData::Unknown { code, ref data } => write_data(*code, data, writer)?,
|
AtomData::Unknown { code, ref data } => write_data(*code, data, writer)?,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -689,7 +692,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_signed_int(int: i32, writer: &mut AtomWriterCompanion<'_>) -> Result<()> {
|
fn write_signed_int(int: i32, writer: &mut AtomWriterCompanion<'_>) -> Result<()> {
|
||||||
write_int(21, int.to_be_bytes(), 4, writer)
|
write_int(BE_SIGNED_INTEGER, int.to_be_bytes(), 4, writer)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bytes_to_occupy_uint(uint: u32) -> usize {
|
fn bytes_to_occupy_uint(uint: u32) -> usize {
|
||||||
|
@ -706,7 +709,12 @@ fn bytes_to_occupy_uint(uint: u32) -> usize {
|
||||||
|
|
||||||
fn write_unsigned_int(uint: u32, writer: &mut AtomWriterCompanion<'_>) -> Result<()> {
|
fn write_unsigned_int(uint: u32, writer: &mut AtomWriterCompanion<'_>) -> Result<()> {
|
||||||
let bytes_needed = bytes_to_occupy_uint(uint);
|
let bytes_needed = bytes_to_occupy_uint(uint);
|
||||||
write_int(22, uint.to_be_bytes(), bytes_needed, writer)
|
write_int(
|
||||||
|
BE_UNSIGNED_INTEGER,
|
||||||
|
uint.to_be_bytes(),
|
||||||
|
bytes_needed,
|
||||||
|
writer,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_int(
|
fn write_int(
|
||||||
|
@ -719,15 +727,19 @@ fn write_int(
|
||||||
write_data(flags, &bytes[4 - bytes_needed..], writer)
|
write_data(flags, &bytes[4 - bytes_needed..], writer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn write_bool(b: bool, writer: &mut AtomWriterCompanion<'_>) -> Result<()> {
|
||||||
|
write_int(BE_SIGNED_INTEGER, i32::from(b).to_be_bytes(), 1, writer)
|
||||||
|
}
|
||||||
|
|
||||||
fn write_picture(picture: &Picture, writer: &mut AtomWriterCompanion<'_>) -> Result<()> {
|
fn write_picture(picture: &Picture, writer: &mut AtomWriterCompanion<'_>) -> Result<()> {
|
||||||
match picture.mime_type {
|
match picture.mime_type {
|
||||||
// GIF is deprecated
|
// GIF is deprecated
|
||||||
Some(MimeType::Gif) => write_data(12, &picture.data, writer),
|
Some(MimeType::Gif) => write_data(12, &picture.data, writer),
|
||||||
Some(MimeType::Jpeg) => write_data(13, &picture.data, writer),
|
Some(MimeType::Jpeg) => write_data(JPEG, &picture.data, writer),
|
||||||
Some(MimeType::Png) => write_data(14, &picture.data, writer),
|
Some(MimeType::Png) => write_data(PNG, &picture.data, writer),
|
||||||
Some(MimeType::Bmp) => write_data(27, &picture.data, writer),
|
Some(MimeType::Bmp) => write_data(BMP, &picture.data, writer),
|
||||||
// We'll assume implicit (0) was the intended type
|
// We'll assume implicit (0) was the intended type
|
||||||
None => write_data(0, &picture.data, writer),
|
None => write_data(RESERVED, &picture.data, writer),
|
||||||
_ => Err(FileEncodingError::new(
|
_ => Err(FileEncodingError::new(
|
||||||
FileType::Mp4,
|
FileType::Mp4,
|
||||||
"Attempted to write an unsupported picture format",
|
"Attempted to write an unsupported picture format",
|
||||||
|
@ -766,7 +778,7 @@ fn write_data(flags: u32, data: &[u8], writer: &mut AtomWriterCompanion<'_>) ->
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::mp4::ilst::write::bytes_to_occupy_uint;
|
use super::bytes_to_occupy_uint;
|
||||||
|
|
||||||
macro_rules! int_test {
|
macro_rules! int_test {
|
||||||
(
|
(
|
||||||
|
|
Loading…
Reference in a new issue