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
9pub 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 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}