fast image operations
Diffstat (limited to 'src/slicing.rs')
| -rw-r--r-- | src/slicing.rs | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/src/slicing.rs b/src/slicing.rs new file mode 100644 index 0000000..947c4ae --- /dev/null +++ b/src/slicing.rs @@ -0,0 +1,51 @@ +use std::ops::{Range, RangeBounds, RangeFull, RangeInclusive}; + +use crate::Image; + +impl<const CHANNELS: usize, T> Image<T, CHANNELS> { + /// ``` + /// let i = fimg::Image::<_, 1>::alloc(5, 5); + /// dbg!(i.bounds((0, 0)..(6, 0))); + /// panic!(); + /// ``` + pub fn bounds<U>(&self, r: impl PBounds) -> std::ops::Range<usize> + where + T: AsRef<[U]>, + { + let r = r.bound(); + let start = match r.start_bound() { + std::ops::Bound::Included(&(x, y)) => self.at(x, y), + std::ops::Bound::Excluded(&(x, y)) => self.at(x, y) + CHANNELS, + std::ops::Bound::Unbounded => 0, + }; + let end = match r.end_bound() { + std::ops::Bound::Included(&(x, y)) => self.at(x, y) + CHANNELS, + std::ops::Bound::Excluded(&(x, y)) => self.at(x, y), + std::ops::Bound::Unbounded => self.buffer.as_ref().len(), + }; + start..end + } +} +pub trait PBounds { + fn bound(self) -> impl RangeBounds<(u32, u32)>; +} +impl PBounds for Range<(u32, u32)> { + fn bound(self) -> impl RangeBounds<(u32, u32)> { + self + } +} +impl PBounds for RangeInclusive<(u32, u32)> { + fn bound(self) -> impl RangeBounds<(u32, u32)> { + self + } +} +impl PBounds for (Range<u32>, u32) { + fn bound(self) -> impl RangeBounds<(u32, u32)> { + (self.0.start, self.1)..(self.0.end, self.1) + } +} +impl PBounds for (u32, Range<u32>) { + fn bound(self) -> impl RangeBounds<(u32, u32)> { + (self.0, self.1.start)..(self.0, self.1.end) + } +} |