Add Header::validate(), don't check in qoi_dec_hdr

This commit is contained in:
Ivan Smirnov 2021-12-01 17:07:21 +00:00
parent fc41914a48
commit 7446a0f171
2 changed files with 17 additions and 9 deletions

View file

@ -1,6 +1,6 @@
use std::mem; use std::mem;
use crate::consts::{QOI_HEADER_SIZE, QOI_INDEX, QOI_MAGIC, QOI_PADDING}; use crate::consts::{QOI_HEADER_SIZE, QOI_INDEX, QOI_PADDING};
use crate::error::{Error, Result}; use crate::error::{Error, Result};
use crate::header::Header; use crate::header::Header;
use crate::pixel::{Pixel, SupportedChannels}; use crate::pixel::{Pixel, SupportedChannels};
@ -182,6 +182,7 @@ pub fn qoi_decode_to_vec(
) -> Result<(Header, Vec<u8>)> { ) -> Result<(Header, Vec<u8>)> {
let data = data.as_ref(); let data = data.as_ref();
let header = qoi_decode_header(data)?; let header = qoi_decode_header(data)?;
header.validate()?;
let channels = channels.maybe_channels().unwrap_or(header.channels); let channels = channels.maybe_channels().unwrap_or(header.channels);
match channels { match channels {
3 => Ok((header, qoi_decode_impl::<3>(data, header.n_pixels())?)), 3 => Ok((header, qoi_decode_impl::<3>(data, header.n_pixels())?)),
@ -198,12 +199,5 @@ pub fn qoi_decode_header(data: impl AsRef<[u8]>) -> Result<Header> {
} }
let mut bytes = [0_u8; QOI_HEADER_SIZE]; let mut bytes = [0_u8; QOI_HEADER_SIZE];
bytes.copy_from_slice(&data[..QOI_HEADER_SIZE]); bytes.copy_from_slice(&data[..QOI_HEADER_SIZE]);
let header = Header::from_bytes(bytes); Ok(Header::from_bytes(bytes))
if unlikely(header.magic != QOI_MAGIC) {
return Err(Error::InvalidMagic { magic: header.magic });
}
if unlikely(header.height == 0 || header.width == 0) {
return Err(Error::EmptyImage { width: header.width, height: header.height });
}
Ok(header)
} }

View file

@ -1,5 +1,7 @@
use crate::colorspace::ColorSpace; use crate::colorspace::ColorSpace;
use crate::consts::{QOI_HEADER_SIZE, QOI_MAGIC}; use crate::consts::{QOI_HEADER_SIZE, QOI_MAGIC};
use crate::error::{Error, Result};
use crate::utils::unlikely;
#[derive(Copy, Clone, Debug, PartialEq, Eq)] #[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct Header { pub struct Header {
@ -61,4 +63,16 @@ impl Header {
pub const fn n_pixels(&self) -> usize { pub const fn n_pixels(&self) -> usize {
(self.width as usize).saturating_mul(self.height as usize) (self.width as usize).saturating_mul(self.height as usize)
} }
#[inline]
pub fn validate(&self) -> Result<()> {
if unlikely(self.magic != QOI_MAGIC) {
return Err(Error::InvalidMagic { magic: self.magic });
} else if unlikely(self.height == 0 || self.width == 0) {
return Err(Error::EmptyImage { width: self.width, height: self.height });
} else if unlikely(self.channels < 3 || self.channels > 4) {
return Err(Error::InvalidChannels { channels: self.channels });
}
Ok(())
}
} }