Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions mp4parse/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3815,8 +3815,10 @@ fn read_colr<T: Read>(
/// Rotation in the positive (that is, anticlockwise) direction
/// Visualized in terms of starting with (⥠) UPWARDS HARPOON WITH BARB LEFT FROM BAR
/// similar to a DIGIT ONE (1)
#[derive(Default)]
pub enum ImageRotation {
/// ⥠ UPWARDS HARPOON WITH BARB LEFT FROM BAR
#[default]
D0,
/// ⥞ LEFTWARDS HARPOON WITH BARB DOWN FROM BAR
D90,
Expand Down
40 changes: 34 additions & 6 deletions mp4parse_capi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,11 @@ pub struct Mp4parseFragmentInfo {

/// Parser state for MP4 files, exposed to C callers via raw pointer.
///
/// # Thread safety
///
/// A parser instance must not be accessed from multiple threads
/// concurrently. The caller is responsible for serializing all access.
///
/// # Pointer stability
///
/// Several C API functions return raw pointers into data cached on this
Expand Down Expand Up @@ -341,7 +346,7 @@ pub enum Mp4parseAvifLoopMode {
}

#[repr(C)]
#[derive(Debug)]
#[derive(Debug, Default)]
pub struct Mp4parseAvifInfo {
pub premultiplied_alpha: bool,
pub major_brand: [u8; 4],
Expand Down Expand Up @@ -383,7 +388,7 @@ pub struct Mp4parseAvifInfo {
}

#[repr(C)]
#[derive(Debug)]
#[derive(Debug, Default)]
pub struct Mp4parseAvifImage {
pub primary_image: Mp4parseByteData,
/// If no alpha item exists, members' `.length` will be 0 and `.data` will be null
Expand Down Expand Up @@ -431,6 +436,12 @@ impl ContextParser for Mp4parseParser {
}
}

/// Parser state for AVIF files, exposed to C callers via raw pointer.
///
/// # Thread safety
///
/// A parser instance must not be accessed from multiple threads
/// concurrently. The caller is responsible for serializing all access.
#[derive(Default)]
pub struct Mp4parseAvifParser {
context: AvifContext,
Expand Down Expand Up @@ -499,6 +510,10 @@ impl Read for Mp4parseIo {
}
let rv = self.read.unwrap()(buf.as_mut_ptr(), buf.len(), self.userdata);
if rv >= 0 {
assert!(
rv as usize <= buf.len(),
"read callback returned more bytes than buffer size"
);
Ok(rv as usize)
} else {
Err(std::io::Error::other("I/O error in Mp4parseIo Read impl"))
Expand Down Expand Up @@ -680,7 +695,10 @@ pub unsafe extern "C" fn mp4parse_get_track_info(
let track = &context.tracks[track_index];

if let (Some(timescale), Some(context_timescale)) = (track.timescale, context.timescale) {
info.time_scale = timescale.0 as u32;
info.time_scale = match timescale.0.try_into() {
Ok(v) => v,
Err(_) => return Mp4parseStatus::Invalid,
};
let media_time: CheckedInteger<u64> = track
.media_time
.map_or(0.into(), |media_time| media_time.0.into());
Expand Down Expand Up @@ -831,8 +849,12 @@ fn get_track_audio_info(
}
}
};
sample_info.channels = audio.channelcount as u16;
sample_info.channels =
u16::try_from(audio.channelcount).map_err(|_| Mp4parseStatus::Invalid)?;
sample_info.bit_depth = audio.samplesize;
if audio.samplerate < 0.0 || audio.samplerate > u32::MAX as f64 {
return Err(Mp4parseStatus::Invalid);
}
sample_info.sample_rate = audio.samplerate as u32;
// sample_info.profile is handled below on a per case basis

Expand Down Expand Up @@ -1166,6 +1188,9 @@ pub unsafe extern "C" fn mp4parse_avif_get_info(
return Mp4parseStatus::BadArg;
}

// Initialize fields to default values to ensure all fields are always valid.
*avif_info = Default::default();

if let Ok(info) = mp4parse_avif_get_info_safe((*parser).context()) {
*avif_info = info;
Mp4parseStatus::Ok
Expand Down Expand Up @@ -1348,6 +1373,9 @@ pub unsafe extern "C" fn mp4parse_avif_get_image(
return Mp4parseStatus::BadArg;
}

// Initialize fields to default values to ensure all fields are always valid.
*avif_image = Default::default();

if let Ok(image) = mp4parse_avif_get_image_safe(&*parser) {
*avif_image = image;
Mp4parseStatus::Ok
Expand Down Expand Up @@ -1382,7 +1410,7 @@ pub unsafe extern "C" fn mp4parse_get_indice_table(
track_id: u32,
indices: *mut Mp4parseByteData,
) -> Mp4parseStatus {
if parser.is_null() {
if parser.is_null() || indices.is_null() {
return Mp4parseStatus::BadArg;
}

Expand Down Expand Up @@ -1561,7 +1589,7 @@ pub unsafe extern "C" fn mp4parse_is_fragmented(
track_id: u32,
fragmented: *mut u8,
) -> Mp4parseStatus {
if parser.is_null() {
if parser.is_null() || fragmented.is_null() {
return Mp4parseStatus::BadArg;
}

Expand Down
Loading