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}