diff --git a/crates/gif/src/write.rs b/crates/gif/src/write.rs index 7648c3f26..bc8a4be97 100644 --- a/crates/gif/src/write.rs +++ b/crates/gif/src/write.rs @@ -90,10 +90,7 @@ pub fn prepare_frame(width: u32, height: u32, mut pixels: Vec, speed: i32) - if !(1..=30).contains(&speed) { return Err(Error::InvalidSpeed(speed)); } - let expected = usize::from(width) - .checked_mul(usize::from(height)) - .and_then(|pixels| pixels.checked_mul(4)) - .ok_or(Error::Dimensions { width: u32::from(width), height: u32::from(height) })?; + let expected = rgba_len(width, height)?; if pixels.len() != expected { return Err(Error::FrameLength { index: 0, actual: pixels.len(), expected }); } @@ -101,6 +98,13 @@ pub fn prepare_frame(width: u32, height: u32, mut pixels: Vec, speed: i32) - Ok(PreparedFrame { width, height, frame }) } +fn rgba_len(width: u16, height: u16) -> Result { + usize::from(width) + .checked_mul(usize::from(height)) + .and_then(|pixels| pixels.checked_mul(4)) + .ok_or(Error::Dimensions { width: u32::from(width), height: u32::from(height) }) +} + fn dimensions(width: u32, height: u32) -> Result<(u16, u16), Error> { if width == 0 || height == 0 || width > u32::from(u16::MAX) || height > u32::from(u16::MAX) { return Err(Error::Dimensions { width, height }); @@ -135,6 +139,10 @@ impl AnimationWriter { /// Encode and append one full-canvas RGBA8 frame. pub fn write_frame(&mut self, frame: RgbaFrame<'_>) -> Result<(), Error> { + let expected = rgba_len(self.width, self.height)?; + if frame.pixels.len() != expected { + return Err(Error::FrameLength { index: self.frames_written, actual: frame.pixels.len(), expected }); + } let prepared = prepare_frame(u32::from(self.width), u32::from(self.height), frame.pixels.to_vec(), self.options.speed).map_err(|error| match error { Error::FrameLength { actual, expected, .. } => Error::FrameLength { index: self.frames_written, actual, expected },