melvin_ob/imaging/
sub_buffer.rs

1use image::{GenericImage, GenericImageView};
2use std::ops::{Deref, DerefMut};
3
4use crate::util::Vec2D;
5
6/// A sub-region of an image, represented as a buffer with bounds.
7/// This struct allows for accessing and modifying a subsection of the image efficiently.
8pub(crate) struct SubBuffer<T> {
9    /// The underlying image buffer.
10    pub(crate) buffer: T,
11    /// The size of the entire buffer in pixels.
12    pub(crate) buffer_size: Vec2D<u32>,
13    /// The offset of this sub-buffer within the overall buffer.
14    pub(crate) offset: Vec2D<u32>,
15    /// The dimensions of the sub-buffer.
16    pub(crate) size: Vec2D<u32>,
17}
18
19impl<T> GenericImageView for SubBuffer<T>
20where
21    T: Deref,
22    T::Target: GenericImageView + Sized,
23{
24    type Pixel = <<T as Deref>::Target as GenericImageView>::Pixel;
25
26    /// Returns the dimensions of the sub-buffer in pixels.
27    fn dimensions(&self) -> (u32, u32) { (self.size.x(), self.size.y()) }
28
29    /// Fetches a pixel from the sub-buffer at the specified coordinates.
30    ///
31    /// # Arguments
32    ///
33    /// * `x` - The x-coordinate of the pixel to fetch.
34    /// * `y` - The y-coordinate of the pixel to fetch.
35    ///
36    /// # Returns
37    ///
38    /// The pixel at the specified coordinates.
39    fn get_pixel(&self, x: u32, y: u32) -> Self::Pixel {
40        let x_loc = (x + self.offset.x()) % self.buffer_size.x();
41        let y_loc = (y + self.offset.y()) % self.buffer_size.y();
42        self.buffer.get_pixel(x_loc, y_loc)
43    }
44}
45
46impl<T> GenericImage for SubBuffer<T>
47where
48    T: DerefMut,
49    T::Target: GenericImage + Sized,
50{
51    /// Fetches a mutable reference to a pixel within the sub-buffer at the specified coordinates.
52    ///
53    /// # Arguments
54    ///
55    /// * `x` - The x-coordinate of the pixel to fetch.
56    /// * `y` - The y-coordinate of the pixel to fetch.
57    ///
58    /// # Returns
59    ///
60    /// A mutable reference to the pixel at the specified coordinates.
61    #[allow(deprecated)]
62    fn get_pixel_mut(&mut self, x: u32, y: u32) -> &mut Self::Pixel {
63        let x_loc = (x + self.offset.x()) % self.buffer_size.x();
64        let y_loc = (y + self.offset.y()) % self.buffer_size.y();
65        self.buffer.get_pixel_mut(x_loc, y_loc)
66    }
67
68    /// Writes a pixel to the sub-buffer at the specified coordinates.
69    ///
70    /// # Arguments
71    ///
72    /// * `x` - The x-coordinate where the pixel will be written.
73    /// * `y` - The y-coordinate where the pixel will be written.
74    /// * `pixel` - The pixel to write at the specified coordinates.
75    fn put_pixel(&mut self, x: u32, y: u32, pixel: Self::Pixel) {
76        let x_loc = (x + self.offset.x()) % self.buffer_size.x();
77        let y_loc = (y + self.offset.y()) % self.buffer_size.y();
78        self.buffer.put_pixel(x_loc, y_loc, pixel);
79    }
80
81    /// Blends a pixel with the pixel at the specified coordinates within the sub-buffer.
82    ///
83    /// # Arguments
84    ///
85    /// * `x` - The x-coordinate where the pixel will be blended.
86    /// * `y` - The y-coordinate where the pixel will be blended.
87    /// * `pixel` - The pixel to blend at the specified coordinates.
88    #[allow(deprecated)]
89    fn blend_pixel(&mut self, x: u32, y: u32, pixel: Self::Pixel) {
90        let x_loc = (x + self.offset.x()) % self.buffer_size.x();
91        let y_loc = (y + self.offset.y()) % self.buffer_size.y();
92        self.buffer.blend_pixel(x_loc, y_loc, pixel);
93    }
94}