Validation checks for RawImage construction
This commit is contained in:
parent
9dfd1b867c
commit
16842eb33d
2 changed files with 29 additions and 0 deletions
11
src/error.rs
11
src/error.rs
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::colors::{BitDepth, ColorType};
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
|
|
@ -11,6 +12,8 @@ pub enum PngError {
|
||||||
InvalidData,
|
InvalidData,
|
||||||
TruncatedData,
|
TruncatedData,
|
||||||
ChunkMissing(&'static str),
|
ChunkMissing(&'static str),
|
||||||
|
InvalidDepthForType(BitDepth, ColorType),
|
||||||
|
IncorrectDataLength(usize, usize),
|
||||||
Other(Box<str>),
|
Other(Box<str>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -30,6 +33,14 @@ impl fmt::Display for PngError {
|
||||||
}
|
}
|
||||||
PngError::APNGNotSupported => f.write_str("APNG files are not (yet) supported"),
|
PngError::APNGNotSupported => f.write_str("APNG files are not (yet) supported"),
|
||||||
PngError::ChunkMissing(s) => write!(f, "Chunk {} missing or empty", s),
|
PngError::ChunkMissing(s) => write!(f, "Chunk {} missing or empty", s),
|
||||||
|
PngError::InvalidDepthForType(d, ref c) => {
|
||||||
|
write!(f, "Invalid bit depth {} for color type {}", d, c)
|
||||||
|
}
|
||||||
|
PngError::IncorrectDataLength(l1, l2) => write!(
|
||||||
|
f,
|
||||||
|
"Data length {} does not match the expected length {}",
|
||||||
|
l1, l2
|
||||||
|
),
|
||||||
PngError::Other(ref s) => f.write_str(s),
|
PngError::Other(ref s) => f.write_str(s),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
18
src/lib.rs
18
src/lib.rs
|
|
@ -331,6 +331,24 @@ impl RawImage {
|
||||||
bit_depth: BitDepth,
|
bit_depth: BitDepth,
|
||||||
data: Vec<u8>,
|
data: Vec<u8>,
|
||||||
) -> Result<Self, PngError> {
|
) -> Result<Self, PngError> {
|
||||||
|
// Validate bit depth
|
||||||
|
let valid_depth = match color_type {
|
||||||
|
ColorType::Grayscale { .. } => true,
|
||||||
|
ColorType::Indexed { .. } => (bit_depth as u8) <= 8,
|
||||||
|
_ => (bit_depth as u8) >= 8,
|
||||||
|
};
|
||||||
|
if !valid_depth {
|
||||||
|
return Err(PngError::InvalidDepthForType(bit_depth, color_type));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate data length
|
||||||
|
let bpp = bit_depth as usize * color_type.channels_per_pixel() as usize;
|
||||||
|
let row_bytes = (bpp * width as usize + 7) / 8;
|
||||||
|
let expected_len = row_bytes * height as usize;
|
||||||
|
if data.len() != expected_len {
|
||||||
|
return Err(PngError::IncorrectDataLength(data.len(), expected_len));
|
||||||
|
}
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
png: Arc::new(PngImage {
|
png: Arc::new(PngImage {
|
||||||
ihdr: IhdrData {
|
ihdr: IhdrData {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue