unimage_rust/
lib.rs

1#![allow(non_upper_case_globals)]
2#![allow(non_camel_case_types)]
3#![allow(non_snake_case)]
4
5use std::{ffi::CStr, fmt, mem::transmute};
6
7include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
8
9///
10/// The pixel formats.
11///
12#[repr(u8)]
13pub enum UnimageFormat {
14    None = 0,
15    RGB = 1,
16    RGBA = 2,
17}
18
19///
20/// A image processor. it can load image, resize it or clip it.
21///
22pub struct UnimageProcessor {
23    ptr: *mut ::std::os::raw::c_void,
24}
25
26///
27/// Error with message.
28///
29#[derive(Debug)]
30pub struct UnimageError {
31    message: String,
32}
33
34impl fmt::Display for UnimageError {
35    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36        write!(f, "{}", self.message)
37    }
38}
39
40impl UnimageError {
41    fn from(err: String) -> UnimageError {
42        UnimageError { message: err }
43    }
44}
45
46impl UnimageProcessor {
47    ///
48    /// Create a UnimageProcessor instance.
49    ///
50    pub fn new() -> UnimageProcessor {
51        unsafe {
52            UnimageProcessor {
53                ptr: unimage_processor_create(),
54            }
55        }
56    }
57
58    ///
59    /// Get the instance pointer
60    ///
61    pub unsafe fn get_instance(&self) -> *mut ::std::os::raw::c_void {
62        self.ptr
63    }
64
65    ///
66    /// Load pixels from a pointer.
67    ///
68    pub fn load_raw(&mut self, data: *mut u8, width: i32, height: i32, format: UnimageFormat) {
69        unsafe { unimage_processor_load_raw(self.ptr, data, width, height, format as u8) }
70    }
71
72    ///
73    /// Load pixels from a `Vec<u8>`.
74    ///
75    pub fn load_raw_from_vec(
76        &mut self,
77        data: &mut Vec<u8>,
78        width: i32,
79        height: i32,
80        format: UnimageFormat,
81    ) {
82        unsafe {
83            unimage_processor_load_raw(self.ptr, data.as_mut_ptr(), width, height, format as u8)
84        }
85    }
86
87    ///
88    /// Load pixels from a Slice.
89    ///
90    pub fn load_raw_from_slice(
91        &mut self,
92        data: &mut [u8],
93        width: i32,
94        height: i32,
95        format: UnimageFormat,
96    ) {
97        unsafe {
98            unimage_processor_load_raw(self.ptr, data.as_mut_ptr(), width, height, format as u8)
99        }
100    }
101
102    ///
103    /// Load an image from data, if there is something wrong, it will return an error.
104    ///
105    pub fn load(&mut self, data: *mut u8, len: u32) -> Result<(), UnimageError> {
106        let success = unsafe { unimage_processor_load(self.ptr, data, len) };
107
108        if success == 0 {
109            Err(UnimageError::from(self.get_error_message()))
110        } else {
111            Ok(())
112        }
113    }
114
115    ///
116    /// Load an image from data, if there is something wrong, it will return an error.
117    ///
118    pub fn load_from_vec(&mut self, data: &mut Vec<u8>) -> Result<(), UnimageError> {
119        let success = unsafe {
120            unimage_processor_load(self.ptr, data.as_mut_ptr(), data.len().try_into().unwrap())
121        };
122
123        if success == 0 {
124            Err(UnimageError::from(self.get_error_message()))
125        } else {
126            Ok(())
127        }
128    }
129
130    ///
131    /// Load an image from data, if there is something wrong, it will return an error.
132    ///
133    pub fn load_from_slice(&mut self, data: &mut [u8]) -> Result<(), UnimageError> {
134        let success = unsafe {
135            unimage_processor_load(self.ptr, data.as_mut_ptr(), data.len().try_into().unwrap())
136        };
137
138        if success == 0 {
139            Err(UnimageError::from(self.get_error_message()))
140        } else {
141            Ok(())
142        }
143    }
144
145    ///
146    /// Get the width of image.
147    ///
148    pub fn get_width(&self) -> i32 {
149        unsafe { unimage_processor_get_width(self.ptr) }
150    }
151
152    ///
153    /// Get the height of image.
154    ///
155    pub fn get_height(&self) -> i32 {
156        unsafe { unimage_processor_get_height(self.ptr) }
157    }
158
159    ///
160    /// Get the pixel format of image.
161    ///
162    pub fn get_format(&self) -> UnimageFormat {
163        unsafe { transmute::<u8, UnimageFormat>(unimage_processor_get_format(self.ptr)) }
164    }
165
166    ///
167    /// Get the last error message.
168    ///
169    pub fn get_error_message(&self) -> String {
170        unsafe {
171            let c_str = CStr::from_ptr(unimage_processor_get_error_message(self.ptr));
172            let str = c_str.to_str().unwrap();
173            String::from(str)
174        }
175    }
176
177    ///
178    /// Resize the image.
179    ///
180    pub fn resize(&mut self, width: i32, height: i32) -> Result<(), UnimageError> {
181        let success = unsafe { unimage_processor_resize(self.ptr, width, height) };
182
183        if success == 0 {
184            Err(UnimageError::from(self.get_error_message()))
185        } else {
186            Ok(())
187        }
188    }
189
190    ///
191    /// Get the buffer of processor, it will return a pointer that points to pixels data.
192    /// If it doesn't load any image, it will return a nullptr.
193    ///
194    pub unsafe fn get_buffer_as_mut(&mut self) -> *mut u8 {
195        unimage_processor_get_buffer(self.ptr)
196    }
197
198    ///
199    /// Get the buffer of processor, it will return a pointer that points to pixels data.
200    /// If it doesn't load any image, it will return a nullptr.
201    ///
202    pub unsafe fn get_buffer(&self) -> *const u8 {
203        unimage_processor_get_buffer(self.ptr)
204    }
205
206    ///
207    /// Clone the processor instance and the image buffer in it.
208    /// If there is something wrong, it will return a error.
209    ///
210    pub fn try_clone(&self) -> Result<Self, UnimageError> {
211        let new = UnimageProcessor::new();
212        let success = unsafe { unimage_processor_copy_from(new.ptr, self.ptr) };
213
214        if success == 0 {
215            let err = UnimageError::from(self.get_error_message());
216            drop(new);
217            Err(err)
218        } else {
219            Ok(new)
220        }
221    }
222
223    ///
224    /// Clip the image.
225    ///
226    pub fn clip(&mut self, x: i32, y: i32, width: i32, height: i32) -> Result<(), UnimageError> {
227        let success = unsafe { unimage_processor_clip(self.ptr, x, y, width, height) };
228
229        if success == 0 {
230            Err(UnimageError::from(self.get_error_message()))
231        } else {
232            Ok(())
233        }
234    }
235}
236
237impl Clone for UnimageProcessor {
238    ///
239    /// Clone the processor instance and the image buffer in it.
240    ///
241    fn clone(&self) -> Self {
242        self.try_clone().unwrap()
243    }
244}
245
246impl Drop for UnimageProcessor {
247    ///
248    /// Release the processor instance and the buffer in it.
249    ///
250    fn drop(&mut self) {
251        unsafe { unimage_processor_free(self.ptr) }
252    }
253}