pub fn find_start_code(data: &[u8], from: usize) -> Option<usize> {
if data.len() < from + 3 {
return None;
}
memchr::memmem::find(&data[from..], b"\x00\x00\x01").map(|rel| from + rel)
}
pub fn skip_start_code(data: &[u8], pos: usize) -> Option<usize> {
if pos + 2 >= data.len() {
return None;
}
if data[pos] == 0x00 && data[pos + 1] == 0x00 {
if pos + 3 < data.len() && data[pos + 2] == 0x00 && data[pos + 3] == 0x01 {
return Some(pos + 4); }
if data[pos + 2] == 0x01 {
return Some(pos + 3); }
}
None
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn find_start_code_3byte() {
let data = [0x00, 0x00, 0x01, 0x65];
assert_eq!(find_start_code(&data, 0), Some(0));
}
#[test]
fn find_start_code_4byte() {
let data = [0x00, 0x00, 0x00, 0x01, 0x65];
assert_eq!(find_start_code(&data, 0), Some(1));
}
#[test]
fn find_start_code_offset() {
let data = [0xFF, 0xFF, 0x00, 0x00, 0x01, 0x09];
assert_eq!(find_start_code(&data, 0), Some(2));
}
#[test]
fn find_start_code_none() {
let data = [0x00, 0x00, 0x00, 0x00];
assert_eq!(find_start_code(&data, 0), None);
}
#[test]
fn find_start_code_too_short() {
let data = [0x00, 0x00];
assert_eq!(find_start_code(&data, 0), None);
}
#[test]
fn skip_3byte() {
let data = [0x00, 0x00, 0x01, 0x65];
assert_eq!(skip_start_code(&data, 0), Some(3));
}
#[test]
fn skip_4byte() {
let data = [0x00, 0x00, 0x00, 0x01, 0x65];
assert_eq!(skip_start_code(&data, 0), Some(4));
}
#[test]
fn skip_not_a_start_code() {
let data = [0xFF, 0x00, 0x01, 0x65];
assert_eq!(skip_start_code(&data, 0), None);
}
}