Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 1 addition & 7 deletions src/codecs/avif/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,7 @@ impl<W: Write> ImageEncoder for AvifEncoder<W> {
height: u32,
color: ExtendedColorType,
) -> ImageResult<()> {
let expected_buffer_len = color.buffer_size(width, height);
assert_eq!(
expected_buffer_len,
data.len() as u64,
"Invalid buffer length: expected {expected_buffer_len} got {} for {width}x{height} image",
data.len(),
);
color.assert_buf_len(width, height, data);

self.set_color(color);
// `ravif` needs strongly typed data so let's convert. We can either use a temporarily
Expand Down
10 changes: 2 additions & 8 deletions src/codecs/bmp/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ impl<W: Write> BmpEncoder<W> {
color_type: ExtendedColorType,
palette: Option<&[[u8; 3]]>,
) -> ImageResult<()> {
color_type.assert_buf_len(width, height, image);

if palette.is_some()
&& color_type != ExtendedColorType::L1
&& color_type != ExtendedColorType::L8
Expand All @@ -77,14 +79,6 @@ impl<W: Write> BmpEncoder<W> {
)));
}

let expected_buffer_len = color_type.buffer_size(width, height);
assert_eq!(
expected_buffer_len,
image.len() as u64,
"Invalid buffer length: expected {expected_buffer_len} got {} for {width}x{height} image",
image.len(),
);

let bmp_header_size = BITMAPFILEHEADER_SIZE;

let (dib_header_size, bits_per_pixel, palette_color_count) =
Expand Down
2 changes: 2 additions & 0 deletions src/codecs/farbfeld.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,8 @@ impl<W: Write> ImageEncoder for FarbfeldEncoder<W> {
height: u32,
color_type: ExtendedColorType,
) -> ImageResult<()> {
color_type.assert_buf_len(width, height, buf);

if color_type != ExtendedColorType::Rgba16 {
return Err(ImageError::Unsupported(
UnsupportedError::from_format_and_kind(
Expand Down
4 changes: 4 additions & 0 deletions src/codecs/gif.rs
Original file line number Diff line number Diff line change
Expand Up @@ -504,13 +504,16 @@ impl<W: Write> GifEncoder<W> {
}

/// Encode a single image.
#[track_caller]
pub fn encode(
&mut self,
data: &[u8],
width: u32,
height: u32,
color: ExtendedColorType,
) -> ImageResult<()> {
color.assert_buf_len(width, height, data);

let (width, height) = self.gif_dimensions(width, height)?;
match color {
ExtendedColorType::Rgb8 => {
Expand Down Expand Up @@ -633,6 +636,7 @@ impl<W: Write> GifEncoder<W> {
}
}
impl<W: Write> ImageEncoder for GifEncoder<W> {
#[track_caller]
fn write_image(
mut self,
buf: &[u8],
Expand Down
4 changes: 4 additions & 0 deletions src/codecs/hdr/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,20 @@ pub struct HdrEncoder<W: Write> {
}

impl<W: Write> ImageEncoder for HdrEncoder<W> {
#[track_caller]
fn write_image(
self,
unaligned_bytes: &[u8],
width: u32,
height: u32,
color_type: ExtendedColorType,
) -> ImageResult<()> {
color_type.assert_buf_len(width, height, unaligned_bytes);

match color_type {
ExtendedColorType::Rgb32F => {
let bytes_per_pixel = color_type.bits_per_pixel() as usize / 8;

let rgbe_pixels = unaligned_bytes
.chunks_exact(bytes_per_pixel)
.map(|bytes| to_rgbe8(Rgb::<f32>(bytemuck::pod_read_unaligned(bytes))));
Expand Down
8 changes: 1 addition & 7 deletions src/codecs/ico/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,13 +139,7 @@ impl<W: Write> ImageEncoder for IcoEncoder<W> {
height: u32,
color_type: ExtendedColorType,
) -> ImageResult<()> {
let expected_buffer_len = color_type.buffer_size(width, height);
assert_eq!(
expected_buffer_len,
buf.len() as u64,
"Invalid buffer length: expected {expected_buffer_len} got {} for {width}x{height} image",
buf.len(),
);
color_type.assert_buf_len(width, height, buf);

let image = IcoFrame::as_png(buf, width, height, color_type)?;
self.encode_images(&[image])
Expand Down
8 changes: 1 addition & 7 deletions src/codecs/jpeg/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,13 +203,7 @@ impl<W: Write> JpegEncoder<W> {
height: u32,
color_type: ExtendedColorType,
) -> ImageResult<()> {
let expected_buffer_len = color_type.buffer_size(width, height);
assert_eq!(
expected_buffer_len,
image.len() as u64,
"Invalid buffer length: expected {expected_buffer_len} got {} for {width}x{height} image",
image.len(),
);
color_type.assert_buf_len(width, height, image);

let (width, height) = match (u16::try_from(width), u16::try_from(height)) {
(Ok(w @ 1..), Ok(h @ 1..)) => (w, h),
Expand Down
8 changes: 1 addition & 7 deletions src/codecs/openexr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -329,13 +329,7 @@ where
height: u32,
color_type: ExtendedColorType,
) -> ImageResult<()> {
let expected_buffer_len = color_type.buffer_size(width, height);
assert_eq!(
expected_buffer_len,
buf.len() as u64,
"Invalid buffer length: expected {expected_buffer_len} got {} for {width}x{height} image",
buf.len(),
);
color_type.assert_buf_len(width, height, buf);

write_buffer(self.0, buf, width, height, color_type)
}
Expand Down
8 changes: 1 addition & 7 deletions src/codecs/png.rs
Original file line number Diff line number Diff line change
Expand Up @@ -872,13 +872,7 @@ impl<W: Write> ImageEncoder for PngEncoder<W> {
) -> ImageResult<()> {
use ExtendedColorType::*;

let expected_buffer_len = color_type.buffer_size(width, height);
assert_eq!(
expected_buffer_len,
buf.len() as u64,
"Invalid buffer length: expected {expected_buffer_len} got {} for {width}x{height} image",
buf.len(),
);
color_type.assert_buf_len(width, height, buf);

// PNG images are big endian. For 16 bit per channel and larger types,
// the buffer may need to be reordered to big endian per the
Expand Down
8 changes: 1 addition & 7 deletions src/codecs/pnm/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -343,13 +343,7 @@ impl<W: Write> ImageEncoder for PnmEncoder<W> {
height: u32,
color_type: ExtendedColorType,
) -> ImageResult<()> {
let expected_buffer_len = color_type.buffer_size(width, height);
assert_eq!(
expected_buffer_len,
buf.len() as u64,
"Invalid buffer length: expected {expected_buffer_len} got {} for {width}x{height} image",
buf.len(),
);
color_type.assert_buf_len(width, height, buf);

self.encode(buf, width, height, color_type)
}
Expand Down
10 changes: 2 additions & 8 deletions src/codecs/qoi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ impl<W: Write> ImageEncoder for QoiEncoder<W> {
height: u32,
color_type: ExtendedColorType,
) -> ImageResult<()> {
color_type.assert_buf_len(width, height, buf);

if !matches!(
color_type,
ExtendedColorType::Rgba8 | ExtendedColorType::Rgb8
Expand All @@ -85,14 +87,6 @@ impl<W: Write> ImageEncoder for QoiEncoder<W> {
));
}

let expected_buffer_len = color_type.buffer_size(width, height);
assert_eq!(
expected_buffer_len,
buf.len() as u64,
"Invalid buffer length: expected {expected_buffer_len} got {} for {width}x{height} image",
buf.len(),
);

// Encode data in QOI
let data = qoi::encode_to_vec(buf, width, height).map_err(encoding_error)?;

Expand Down
8 changes: 1 addition & 7 deletions src/codecs/tga/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,13 +170,7 @@ impl<W: Write> TgaEncoder<W> {
height: u32,
color_type: ExtendedColorType,
) -> ImageResult<()> {
let expected_buffer_len = color_type.buffer_size(width, height);
assert_eq!(
expected_buffer_len,
buf.len() as u64,
"Invalid buffer length: expected {expected_buffer_len} got {} for {width}x{height} image",
buf.len(),
);
color_type.assert_buf_len(width, height, buf);

// Validate dimensions.
if width == 0 || height == 0 {
Expand Down
10 changes: 3 additions & 7 deletions src/codecs/tiff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -799,13 +799,9 @@ impl<W: Write + Seek> ImageEncoder for TiffEncoder<W> {
use tiff::encoder::colortype::{
Gray16, Gray8, RGB32Float, RGBA32Float, RGB16, RGB8, RGBA16, RGBA8,
};
let expected_buffer_len = color_type.buffer_size(width, height);
assert_eq!(
expected_buffer_len,
buf.len() as u64,
"Invalid buffer length: expected {expected_buffer_len} got {} for {width}x{height} image",
buf.len(),
);

color_type.assert_buf_len(width, height, buf);

match color_type {
ExtendedColorType::L8 => self.write_tiff::<Gray8>(width, height, buf),
ExtendedColorType::Rgb8 => self.write_tiff::<RGB8>(width, height, buf),
Expand Down
8 changes: 1 addition & 7 deletions src/codecs/webp/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,7 @@ impl<W: Write> WebPEncoder<W> {
height: u32,
color_type: ExtendedColorType,
) -> ImageResult<()> {
let expected_buffer_len = color_type.buffer_size(width, height);
assert_eq!(
expected_buffer_len,
buf.len() as u64,
"Invalid buffer length: expected {expected_buffer_len} got {} for {width}x{height} image",
buf.len(),
);
color_type.assert_buf_len(width, height, buf);

let color_type = match color_type {
ExtendedColorType::L8 => image_webp::ColorType::L8,
Expand Down
12 changes: 12 additions & 0 deletions src/color.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,18 @@ impl ExtendedColorType {
let row_pitch = (width as u64 * bpp).div_ceil(8);
row_pitch.saturating_mul(height as u64)
}

/// Asserts that the buffer has the correct length for an image of the given dimensions and color.
#[track_caller]
pub(crate) fn assert_buf_len(self, width: u32, height: u32, buf: &[u8]) {
let expected_buffer_len = self.buffer_size(width, height);
assert_eq!(
expected_buffer_len,
buf.len() as u64,
"Invalid buffer length: expected {expected_buffer_len} but got {} for {width}x{height} {self:?} image",
buf.len(),
);
}
}

impl From<ColorType> for ExtendedColorType {
Expand Down
Loading