vips/interpolate.rs
1use crate::{take_vips_error, Error, Result, VipsRegion};
2use std::ffi::CString;
3use std::os::raw::c_void;
4
5/// VipsInterpolate struct wrapping libvips VipsInterpolate
6///
7/// # Example
8/// ```no_run
9/// use vips::*;
10///
11/// fn main() -> Result<()> {
12/// let _instance = VipsInstance::new("app_test", true)?;
13/// let interpolate = VipsInterpolate::bilinear_static();
14/// let method = interpolate.method();
15/// let img = VipsImage::from_file("examples/images/kodim01.png")?;
16/// let region = VipsRegion::new(&img);
17/// let mut out = vec![0u8; 3]; // assuming 3 channels
18/// method.call(&interpolate, ®ion, &mut out, 1.5, 1.5);
19/// Ok(())
20/// }
21/// ```
22pub struct VipsInterpolate {
23 pub c: *mut vips_sys::VipsInterpolate,
24 is_static: bool,
25}
26
27impl Drop for VipsInterpolate {
28 fn drop(&mut self) {
29 if !self.is_static {
30 unsafe {
31 vips_sys::g_object_unref(self.c as *mut c_void);
32 }
33 }
34 }
35}
36
37impl VipsInterpolate {
38 //
39 // ─── STATIC ─────────────────────────────────────────────────────────────────────
40 //
41
42 // will not implement: vips_interpolate ()
43
44 //
45 // ─── CONSTRUCTORS ───────────────────────────────────────────────────────────────
46 //
47
48 /// Create a new VipsInterpolate by nickname
49 ///
50 /// # Arguments
51 /// * `nickname` - The nickname of the interpolation method
52 ///
53 /// # Errors
54 /// Returns an error if the nickname is invalid
55 ///
56 /// # Example
57 /// ```no_run
58 /// use vips::*;
59 /// fn main() -> Result<()> {
60 /// let _instance = VipsInstance::new("app_test", true)?;
61 /// let interpolate = VipsInterpolate::new("bilinear")?;
62 /// let method = interpolate.method();
63 /// let img = VipsImage::from_file("examples/images/kodim01.png")?;
64 /// let region = VipsRegion::new(&img);
65 /// let mut out = vec![0u8; 3]; // assuming 3 channels
66 /// method.call(&interpolate, ®ion, &mut out, 1.5, 1.5);
67 /// Ok(())
68 /// }
69 /// ```
70 pub fn new(nickname: &str) -> Result<VipsInterpolate> {
71 let nickname = CString::new(nickname)
72 .map_err(|_| Error::Other("Invalid nickname: contains null byte".to_string()))?;
73 let c = unsafe { vips_sys::vips_interpolate_new(nickname.as_ptr()) };
74 if c.is_null() {
75 Err(Error::Vips(take_vips_error().unwrap_or_else(|| {
76 "Unknown error from libvips".to_string()
77 })))
78 } else {
79 Ok(VipsInterpolate {
80 c,
81 is_static: false,
82 })
83 }
84 }
85
86 /// Create a new nearest static VipsInterpolate
87 ///
88 /// # Returns
89 /// A VipsInterpolate instance for nearest neighbor interpolation
90 ///
91 /// # Example
92 /// ```no_run
93 /// use vips::*;
94 /// fn main() -> Result<()> {
95 /// let _instance = VipsInstance::new("app_test", true)?;
96 /// let interpolate = VipsInterpolate::nearest_static();
97 /// let method = interpolate.method();
98 /// let img = VipsImage::from_file("examples/images/kodim01.png")?;
99 /// let region = VipsRegion::new(&img);
100 /// let mut out = vec![0u8; 3]; // assuming 3 channels
101 /// method.call(&interpolate, ®ion, &mut out, 1.5, 1.5);
102 /// Ok(())
103 /// }
104 /// ```
105 ///
106 pub fn nearest_static() -> VipsInterpolate {
107 let c = unsafe { vips_sys::vips_interpolate_nearest_static() };
108 VipsInterpolate { c, is_static: true }
109 }
110
111 /// Create a new bilinear static VipsInterpolate
112 ///
113 /// # Returns
114 /// A VipsInterpolate instance for bilinear interpolation
115 ///
116 /// # Example
117 /// ```no_run
118 /// use vips::*;
119 ///
120 /// fn main() -> Result<()> {
121 /// let _instance = VipsInstance::new("app_test", true)?;
122 /// let interpolate = VipsInterpolate::bilinear_static();
123 /// let method = interpolate.method();
124 /// let img = VipsImage::from_file("examples/images/kodim01.png")?;
125 /// let region = VipsRegion::new(&img);
126 /// let mut out = vec![0u8; 3]; // assuming 3 channels
127 /// method.call(&interpolate, ®ion, &mut out, 1.5, 1.5);
128 /// Ok(())
129 /// }
130 /// ```
131 pub fn bilinear_static() -> VipsInterpolate {
132 let c = unsafe { vips_sys::vips_interpolate_bilinear_static() };
133 VipsInterpolate { c, is_static: true }
134 }
135
136 //
137 // ─── PROPERTIES ─────────────────────────────────────────────────────────────────
138 //
139
140 /// Get the interpolation method
141 ///
142 /// # Returns
143 /// A VipsInterpolateMethod instance representing the interpolation method
144 ///
145 /// # Example
146 /// ```no_run
147 /// use vips::*;
148 ///
149 /// fn main() -> Result<()> {
150 /// let _instance = VipsInstance::new("app_test", true)?;
151 /// let interpolate = VipsInterpolate::bilinear_static();
152 /// let method = interpolate.method();
153 /// let img = VipsImage::from_file("examples/images/kodim01.png")?;
154 /// let region = VipsRegion::new(&img);
155 /// let mut out = vec![0u8; 3]; // assuming 3 channels
156 /// method.call(&interpolate, ®ion, &mut out, 1.5, 1.5);
157 /// Ok(())
158 /// }
159 /// ```
160 pub fn method(&self) -> VipsInterpolateMethod {
161 let c = unsafe { vips_sys::vips_interpolate_get_method(self.c) };
162 VipsInterpolateMethod { c }
163 }
164
165 /// Get the window size
166 ///
167 /// # Returns
168 /// The window size used by the interpolation method
169 ///
170 /// # Example
171 /// ```no_run
172 /// use vips::*;
173 ///
174 /// fn main() -> Result<()> {
175 /// let interpolate = VipsInterpolate::bilinear_static();
176 /// let window_size = interpolate.window_size();
177 /// println!("Window size: {}", window_size);
178 /// Ok(())
179 /// }
180 /// ```
181 pub fn window_size(&self) -> i32 {
182 unsafe { vips_sys::vips_interpolate_get_window_size(self.c) }
183 }
184
185 /// Get the window offset
186 ///
187 /// # Returns
188 /// The window offset used by the interpolation method
189 ///
190 /// # Example
191 /// ```no_run
192 /// use vips::*;
193 ///
194 /// fn main() -> Result<()> {
195 /// let interpolate = VipsInterpolate::bilinear_static();
196 /// let window_offset = interpolate.window_offset();
197 /// println!("Window offset: {}", window_offset);
198 /// Ok(())
199 /// }
200 /// ```
201 pub fn window_offset(&self) -> i32 {
202 unsafe { vips_sys::vips_interpolate_get_window_offset(self.c) }
203 }
204}
205
206/// Function pointer type for VipsInterpolateMethod
207///
208/// # Example
209/// ```no_run
210/// use vips::*;
211///
212/// fn main() -> Result<()> {
213/// let _instance = VipsInstance::new("app_test", true)?;
214/// let interpolate = VipsInterpolate::bilinear_static();
215/// let method = interpolate.method();
216/// let img = VipsImage::from_file("examples/images/kodim01.png")?;
217/// let region = VipsRegion::new(&img);
218/// let mut out = vec![0u8; 3]; // assuming 3 channels
219/// method.call(&interpolate, ®ion, &mut out, 1.5, 1.5);
220/// Ok(())
221/// }
222/// ```
223pub struct VipsInterpolateMethod {
224 c: vips_sys::VipsInterpolateMethod,
225}
226
227impl VipsInterpolateMethod {
228 /// Call the interpolation method
229 ///
230 /// # Arguments
231 /// * `interpolate` - The VipsInterpolate instance
232 /// * `in_` - The input VipsRegion
233 /// * `out` - The output buffer to write the interpolated pixel
234 /// * `x` - The x coordinate to interpolate
235 /// * `y` - The y coordinate to interpolate
236 ///
237 /// # Example
238 /// ```no_run
239 /// use vips::*;
240 /// fn main() -> Result<()> {
241 /// let interpolate = VipsInterpolate::bilinear_static();
242 /// let _instance = VipsInstance::new("app_test", true)?;
243 /// let img = VipsImage::from_file("examples/images/kodim01.png")?;
244 /// let region = VipsRegion::new(&img);
245 /// let mut out = vec![0u8; 3]; // assuming 3 channels
246 /// let method = interpolate.method();
247 /// method.call(&interpolate, ®ion, &mut out, 1.5, 1.5);
248 /// Ok(())
249 /// }
250 /// ```
251 ///
252 pub fn call(
253 &self,
254 interpolate: &VipsInterpolate,
255 in_: &VipsRegion,
256 out: &mut [u8],
257 x: f64,
258 y: f64,
259 ) {
260 unsafe { self.c.unwrap()(interpolate.c, out.as_mut_ptr() as *mut c_void, in_.c, x, y) }
261 }
262}