Skip to content

Commit 14e93c3

Browse files
authored
Add Image::build and associated error (#399)
1 parent 6d11da9 commit 14e93c3

5 files changed

Lines changed: 66 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
- Fixed bug in x86 interval `OR` function ([#395](https://github.com/mkeeter/fidget/pull/395)),
33
thanks [@Wulfsta](https://github.com/Wulfsta)
44
- Bumped many dependencies
5+
- Add `Image::build` function to build an image from a `Vec<T>` and
6+
`ImageSizeLike`, returning an error if the data size is incorrect.
57

68
# 0.4.2
79
- Change `depth` member in `GeometryPixel` from `u32` to `f32` ([#381](https://github.com/mkeeter/fidget/pull/381))

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

demos/web-editor/crate/Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

fidget-raster/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,5 @@ nalgebra.workspace = true
1818
ordered-float.workspace = true
1919
rand.workspace = true
2020
rayon.workspace = true
21+
thiserror.workspace = true
2122
zerocopy.workspace = true

fidget-raster/src/lib.rs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,23 @@ impl<P, S: ImageSizeLike> Image<P, S> {
325325
);
326326
row * self.width() + col
327327
}
328+
329+
/// Builds an image from its components
330+
///
331+
/// Returns an error if `data` does not match the number of pixels in `size`
332+
pub fn build(data: Vec<P>, size: S) -> Result<Self, BadPixelCount> {
333+
let expected = u64::from(size.width()) * u64::from(size.height());
334+
let actual = data.len();
335+
if expected != actual as u64 {
336+
return Err(BadPixelCount {
337+
expected,
338+
actual,
339+
width: size.width(),
340+
height: size.height(),
341+
});
342+
}
343+
Ok(Self { data, size })
344+
}
328345
}
329346

330347
impl<P, S> Image<P, S> {
@@ -458,3 +475,47 @@ impl<P: Default + Copy + Clone> Image<P, VoxelSize> {
458475

459476
/// Three-channel color image
460477
pub type ColorImage = Image<[u8; 3]>;
478+
479+
/// Error type for image builder
480+
#[derive(thiserror::Error, Debug, PartialEq)]
481+
#[error(
482+
"bad pixel count: expected {expected} ({width} × {height}), got {actual}"
483+
)]
484+
pub struct BadPixelCount {
485+
/// Expected pixel count from size
486+
pub expected: u64,
487+
/// Actual pixel count in data
488+
pub actual: usize,
489+
/// Expected width
490+
pub width: u32,
491+
/// Expected height
492+
pub height: u32,
493+
}
494+
495+
#[cfg(test)]
496+
mod test {
497+
use super::*;
498+
499+
#[test]
500+
fn image_construction() {
501+
let i = Image::build(vec![1, 2, 3, 4, 5, 6], ImageSize::new(2, 3));
502+
assert!(i.is_ok());
503+
504+
let i = Image::build(vec![1, 2, 3, 4, 5, 6], ImageSize::new(3, 2));
505+
assert!(i.is_ok());
506+
507+
let i = Image::build(vec![1, 2, 3, 4, 5], ImageSize::new(2, 3));
508+
let Err(e) = i else {
509+
panic!("expected error, got valid image");
510+
};
511+
assert_eq!(
512+
e,
513+
BadPixelCount {
514+
expected: 6,
515+
actual: 5,
516+
width: 2,
517+
height: 3,
518+
}
519+
);
520+
}
521+
}

0 commit comments

Comments
 (0)