use winnow::{
ModalResult, Parser as _,
binary::le_u32,
error::{ContextError, ErrMode, StrContext},
token::literal,
};
#[derive(Clone, Debug, PartialEq, PartialOrd, Hash)]
pub struct WebpFileHeader {
_file_size: u32,
}
pub fn webp_file_header(input: &mut &[u8]) -> ModalResult<WebpFileHeader, ContextError> {
const RIFF: &[u8] = b"RIFF";
literal(RIFF).void().parse_next(input)?;
const FILE_SIZE_MAX: u32 = u32::MAX - 10_u32;
let file_size: u32 = le_u32.parse_next(input)?;
if file_size > FILE_SIZE_MAX {
log::error!(
"File size was reported as `{file_size}` bytes, but maximum is `{FILE_SIZE_MAX}`! \
Cannot continue parsing..."
);
return Err({
let mut ce = ContextError::new();
ce.push(StrContext::Expected(
winnow::error::StrContextValue::StringLiteral(
"File size was too large to be WebP.",
),
));
ErrMode::Cut(ce)
});
}
const WEBP: &[u8] = b"WEBP";
literal(WEBP).void().parse_next(input)?;
Ok(WebpFileHeader {
_file_size: file_size,
})
}