Skip to main content

rs_vips/
region.rs

1use crate::{
2    bindings::{self, free},
3    error::Error,
4    utils::{result_cond, safe_result_cond},
5    Result, VipsImage,
6};
7use std::ffi::c_void;
8
9/// A small, rectangular part of an image
10pub struct VipsRegion {
11    pub(crate) ctx: *mut bindings::VipsRegion,
12}
13
14impl VipsRegion {
15    pub fn new(image: &VipsImage) -> Result<VipsRegion> {
16        unsafe {
17            let res = bindings::vips_region_new(
18                image
19                    .image
20                    .ctx,
21            );
22            result_cond(
23                !res.is_null(),
24                VipsRegion {
25                    ctx: res,
26                },
27                Error::InitializationError("Cannot initialize VipsRegion".to_string()),
28            )
29        }
30    }
31
32    pub fn width(&self) -> i32 {
33        unsafe { bindings::vips_region_width(self.ctx) }
34    }
35
36    pub fn height(&self) -> i32 {
37        unsafe { bindings::vips_region_height(self.ctx) }
38    }
39
40    /// Generate an area of pixels and return a copy
41    pub fn fetch(&self, left: i32, top: i32, width: i32, height: i32) -> Result<Vec<u8>> {
42        unsafe {
43            let mut len = 0;
44            let ptr = bindings::vips_region_fetch(
45                self.ctx,
46                left,
47                top,
48                width,
49                height,
50                &mut len,
51            );
52            safe_result_cond(
53                !ptr.is_null(),
54                || {
55                    let buffer = std::slice::from_raw_parts(ptr, len).to_vec();
56                    free(ptr as *mut c_void);
57                    buffer
58                },
59                Error::OperationError("Error on vips_region_fetch".to_string()),
60            )
61        }
62    }
63}
64
65impl Drop for VipsRegion {
66    fn drop(&mut self) {
67        unsafe {
68            if !self
69                .ctx
70                .is_null()
71            {
72                bindings::g_object_unref(self.ctx as *mut c_void);
73            }
74        }
75    }
76}