basis_universal/encoding/compressor_image.rs
1use basis_universal_sys as sys;
2pub use basis_universal_sys::ColorU8;
3
4// foreign_types::foreign_type! {
5// /// A Foo.
6// pub unsafe type Foo
7// : Sync + Send // optional
8// {
9// type CType = sys::basisu_image;
10// fn drop = unimplemented!();
11// }
12// }
13
14/// A reference to an image being stored by [CompressorParams](super::CompressorParams). Generally
15/// used to insert the source data that is to be encoded by a [Compressor](super::Compressor).
16pub struct CompressorImageRef(pub *mut sys::basisu_image);
17
18impl CompressorImageRef {
19 /// Sets the image to be completely empty (i.e. 0 width, 0 height). (This was called `clear` in
20 /// the upstream API.)
21 pub fn invalidate(&mut self) {
22 unsafe {
23 sys::image_clear(self.0);
24 }
25 }
26
27 /// Resizes the image to the given width/height
28 ///
29 /// By default the pitch will be equal to the width. To customize this, use `resize_with_pitch`
30 pub fn resize(
31 &mut self,
32 width: u32,
33 height: u32,
34 ) {
35 unsafe {
36 sys::image_resize(self.0, width, height);
37 }
38 }
39
40 /// Resize the image to the given width/height with a custom "pitch". The pitch is the
41 /// offset between rows and is not needed for all formats. By default, the pitch will be equal
42 /// to the width
43 pub fn resize_with_pitch(
44 &mut self,
45 width: u32,
46 height: u32,
47 pitch: u32,
48 ) {
49 unsafe {
50 sys::image_resize_with_pitch(self.0, width, height, pitch);
51 }
52 }
53
54 /// Resize the image and populate it with the given data.
55 ///
56 /// channel_count should be the number of channels in the image (so >=1 and <= 4)
57 pub fn init(
58 &mut self,
59 data: &[u8],
60 width: u32,
61 height: u32,
62 channel_count: u8,
63 ) {
64 unsafe {
65 sys::image_init(self.0, data.as_ptr(), width, height, channel_count as _);
66 }
67 }
68
69 /// Returns the pixel value at a given x,y
70 pub fn pixel_at(
71 &self,
72 width: u32,
73 height: u32,
74 ) -> Option<ColorU8> {
75 unsafe {
76 let mut color = ColorU8 { combined: 0 };
77
78 if sys::image_get_pixel_at_checked(self.0, width, height, &mut color as *mut _) {
79 Some(color)
80 } else {
81 None
82 }
83 }
84 }
85
86 /// Returns teh pixel value at a given x,y without doing bounds checking
87 ///
88 /// # Safety
89 ///
90 /// Accessing pixel out of bounds of the image will result in undefined behavior
91 pub unsafe fn pixel_at_unchecked(
92 &self,
93 width: u32,
94 height: u32,
95 ) -> ColorU8 {
96 sys::image_get_pixel_at_unchecked(self.0, width, height)
97 }
98
99 /// Returns the width of the image in pixels
100 pub fn width(&self) -> u32 {
101 unsafe { sys::image_get_width(self.0) }
102 }
103
104 /// Returns the height of the image in pixels
105 pub fn height(&self) -> u32 {
106 unsafe { sys::image_get_height(self.0) }
107 }
108
109 /// Returns the pitch of the image in pixels, which represents the offset between rows
110 pub fn pitch(&self) -> u32 {
111 unsafe { sys::image_get_pitch(self.0) }
112 }
113
114 /// Returns the total number of pixels in the image
115 pub fn total_pixels(&self) -> u32 {
116 unsafe { sys::image_get_total_pixels(self.0) }
117 }
118
119 /// Returns how many blocks wide the image is, given `w`, the width of a block in pixels
120 pub fn block_width(
121 &self,
122 w: u32,
123 ) -> u32 {
124 unsafe { sys::image_get_block_width(self.0, w) }
125 }
126
127 /// Returns how many blocks high the image is, given `h`, the height of a block in pixels
128 pub fn block_height(
129 &self,
130 h: u32,
131 ) -> u32 {
132 unsafe { sys::image_get_block_height(self.0, h) }
133 }
134
135 /// Returns the number of blocks required to store the image, given `w` and `h`, the width and
136 /// height of a block in pixels
137 pub fn total_blocks(
138 &self,
139 w: u32,
140 h: u32,
141 ) -> u32 {
142 unsafe { sys::image_get_total_blocks(self.0, w, h) }
143 }
144
145 /// Returns a mutable reference to the pixel data as a slice of [ColorU8]
146 pub fn pixel_data_mut(&mut self) -> &mut [ColorU8] {
147 unsafe {
148 let data = sys::image_get_pixel_data(self.0);
149 std::slice::from_raw_parts_mut(data.pData, data.length as usize)
150 }
151 }
152
153 /// Returns a mutable reference to the pixel data as a slice of u8
154 pub fn pixel_data_u8_mut(&mut self) -> &mut [u8] {
155 unsafe {
156 let data = sys::image_get_pixel_data(self.0);
157 std::slice::from_raw_parts_mut(
158 data.pData as *mut u8,
159 data.length as usize * std::mem::size_of::<ColorU8>(),
160 )
161 }
162 }
163
164 /// Returns a mutable reference to the pixel data as a slice of u32
165 pub fn pixel_data_u32_mut(&mut self) -> &mut [u32] {
166 debug_assert_eq!(std::mem::size_of::<u32>(), std::mem::size_of::<ColorU8>());
167 unsafe {
168 let data = sys::image_get_pixel_data(self.0);
169 std::slice::from_raw_parts_mut(data.pData as *mut u32, data.length as usize)
170 }
171 }
172}