vips/buffer.rs
1use crate::{take_vips_error, Error, Result, VipsImage};
2use std::os::raw::{c_char, c_int, c_void};
3use std::ptr::null;
4
5/// Extension trait for thumbnailing from a byte buffer
6///
7/// # Example
8/// ```no_run
9/// use vips::*;
10///
11/// fn main() -> Result<()> {
12/// let _instance = VipsInstance::new("app_test", true)?;
13/// let binding = std::fs::read("./examples/images/kodim01.png")?;
14/// let img_data: &[u8] = binding.as_slice();
15/// let thumbnail = img_data.thumbnail(100, 100)?;
16/// thumbnail.write_to_file("kodim01_thumb.png")?;
17/// Ok(())
18/// }
19/// ```
20///
21pub trait VipsBuffer {
22 fn thumbnail(&self, width: u32, height: u32) -> Result<VipsImage<'_>>;
23}
24
25impl VipsBuffer for &[u8] {
26 /// Create a thumbnail VipsImage from the byte buffer
27 ///
28 /// # Arguments
29 /// * `width` - The desired thumbnail width
30 /// * `height` - The desired thumbnail height
31 ///
32 /// # Errors
33 /// Returns an error if the thumbnail creation fails
34 ///
35 /// # Example
36 /// ```no_run
37 /// use vips::*;
38 ///
39 /// fn main() -> Result<()> {
40 /// let _instance = VipsInstance::new("app_test", true)?;
41 /// let binding = std::fs::read("./examples/images/kodim01.png")?;
42 /// let img_data: &[u8] = binding.as_slice();
43 /// let thumbnail = img_data.thumbnail(100, 100)?;
44 /// thumbnail.write_to_file("kodim01_thumb.png")?;
45 /// Ok(())
46 /// }
47 /// ```
48 ///
49 /// # Safety Note
50 /// The input byte slice must contain valid image data that libvips can decode.
51 /// Providing invalid or corrupted data may lead to undefined behavior.
52 /// Ensure that the data is properly validated before calling this method.
53 ///
54 fn thumbnail(&self, width: u32, height: u32) -> Result<VipsImage<'_>> {
55 unsafe {
56 let mut out = VipsImage::new_memory()?;
57 let ret: c_int = vips_sys::vips_thumbnail_buffer(
58 self.as_ptr() as *mut c_void,
59 self.len(),
60 &mut out.c,
61 width as c_int,
62 c"height".as_ptr(),
63 height as c_int,
64 c"size".as_ptr(),
65 vips_sys::VipsSize::VIPS_SIZE_FORCE,
66 null() as *const c_char,
67 );
68 if ret == 0 {
69 Ok(out)
70 } else {
71 Err(Error::Vips(take_vips_error().unwrap_or_else(|| {
72 "Unknown error from libvips".to_string()
73 })))
74 }
75 }
76 }
77}