Add read_be_u16 and tidy parse_next_chunk

This commit is contained in:
Andrew 2025-01-14 19:06:19 +13:00 committed by Alejandro González
parent 6c7ab5d79f
commit 60911977f6

View file

@ -134,7 +134,7 @@ fn parse_jumbf_box(data: &[u8]) -> Option<(&[u8], &[u8])> {
return None; return None;
} }
let (len, rest) = data.split_at(4); let (len, rest) = data.split_at(4);
let len = u32::from_be_bytes(len.try_into().unwrap()) as usize; let len = read_be_u32(len) as usize;
if len < 8 || len > data.len() { if len < 8 || len > data.len() {
return None; return None;
} }
@ -153,32 +153,25 @@ pub fn parse_next_chunk<'a>(
.get(*byte_offset..*byte_offset + 4) .get(*byte_offset..*byte_offset + 4)
.ok_or(PngError::TruncatedData)?, .ok_or(PngError::TruncatedData)?,
); );
if byte_data.len() < *byte_offset + 12 + length as usize {
return Err(PngError::TruncatedData);
}
*byte_offset += 4; *byte_offset += 4;
let chunk_start = *byte_offset; let chunk_start = *byte_offset;
let chunk_name = byte_data let chunk_name = &byte_data[chunk_start..chunk_start + 4];
.get(chunk_start..chunk_start + 4)
.ok_or(PngError::TruncatedData)?;
if chunk_name == b"IEND" { if chunk_name == b"IEND" {
// End of data // End of data
return Ok(None); return Ok(None);
} }
*byte_offset += 4; *byte_offset += 4;
let data = byte_data let data = &byte_data[*byte_offset..*byte_offset + length as usize];
.get(*byte_offset..*byte_offset + length as usize)
.ok_or(PngError::TruncatedData)?;
*byte_offset += length as usize; *byte_offset += length as usize;
let crc = read_be_u32( let crc = read_be_u32(&byte_data[*byte_offset..*byte_offset + 4]);
byte_data
.get(*byte_offset..*byte_offset + 4)
.ok_or(PngError::TruncatedData)?,
);
*byte_offset += 4; *byte_offset += 4;
let chunk_bytes = byte_data let chunk_bytes = &byte_data[chunk_start..chunk_start + 4 + length as usize];
.get(chunk_start..chunk_start + 4 + length as usize)
.ok_or(PngError::TruncatedData)?;
if !fix_errors && crc32(chunk_bytes) != crc { if !fix_errors && crc32(chunk_bytes) != crc {
return Err(PngError::new(&format!( return Err(PngError::new(&format!(
"CRC Mismatch in {} chunk; May be recoverable by using --fix", "CRC Mismatch in {} chunk; May be recoverable by using --fix",
@ -202,13 +195,13 @@ pub fn parse_ihdr_chunk(
0 => ColorType::Grayscale { 0 => ColorType::Grayscale {
transparent_shade: trns_data transparent_shade: trns_data
.filter(|t| t.len() >= 2) .filter(|t| t.len() >= 2)
.map(|t| u16::from_be_bytes([t[0], t[1]])), .map(|t| read_be_u16(&t[0..2])),
}, },
2 => ColorType::RGB { 2 => ColorType::RGB {
transparent_color: trns_data.filter(|t| t.len() >= 6).map(|t| RGB16 { transparent_color: trns_data.filter(|t| t.len() >= 6).map(|t| RGB16 {
r: u16::from_be_bytes([t[0], t[1]]), r: read_be_u16(&t[0..2]),
g: u16::from_be_bytes([t[2], t[3]]), g: read_be_u16(&t[2..4]),
b: u16::from_be_bytes([t[4], t[5]]), b: read_be_u16(&t[4..6]),
}), }),
}, },
3 => ColorType::Indexed { 3 => ColorType::Indexed {
@ -245,7 +238,12 @@ fn palette_to_rgba(
} }
#[inline] #[inline]
fn read_be_u32(bytes: &[u8]) -> u32 { pub fn read_be_u16(bytes: &[u8]) -> u16 {
u16::from_be_bytes(bytes.try_into().unwrap())
}
#[inline]
pub fn read_be_u32(bytes: &[u8]) -> u32 {
u32::from_be_bytes(bytes.try_into().unwrap()) u32::from_be_bytes(bytes.try_into().unwrap())
} }