rs_vips/
lib.rs

1// (c) Copyright 2019-2025 OLX
2// (c) Copyright 2025 mrdkprj
3#![allow(non_upper_case_globals)]
4#![allow(non_camel_case_types)]
5#![allow(non_snake_case)]
6#![allow(improper_ctypes)]
7#![allow(dead_code)]
8#[macro_use]
9extern crate num_derive;
10extern crate num_traits;
11
12pub mod bindings;
13/// VipsConnection, VipsSource, VipsTarget
14mod connection;
15pub mod error;
16/// VipsImage
17mod image;
18/// VipsInterpolate
19mod interpolate;
20pub mod operator;
21/// Vips Enumerations
22pub mod ops;
23/// VipsBlob
24mod region;
25pub mod utils;
26/// VOption, a list of name-value pairs
27pub mod voption;
28
29pub use connection::*;
30use error::Error;
31pub use image::*;
32pub use interpolate::*;
33pub use region::*;
34use std::ffi::*;
35pub type Result<T> = std::result::Result<T, error::Error>;
36
37pub struct Vips;
38
39/// That's the main type of this crate. Use it to initialize the system
40impl Vips {
41    /// Starts up libvips
42    pub fn init(name: &str) -> Result<()> {
43        let c_name = utils::new_c_string(name)?;
44        let res = unsafe { bindings::vips_init(c_name.as_ptr()) };
45        if res == 0 {
46            Ok(())
47        } else {
48            Err(Error::InitializationError("Failed to init libvips".to_string()))
49        }
50    }
51
52    /// Turn on or off vips leak checking.
53    pub fn leak_set(leak: bool) {
54        unsafe { bindings::vips_leak_set(if leak { 1 } else { 0 }) };
55    }
56
57    /// A structure available to eval callbacks giving information on evaluation progress
58    pub fn progress_set(flag: bool) {
59        unsafe {
60            bindings::vips_progress_set(if flag { 1 } else { 0 });
61        }
62    }
63
64    /// Return the number of bytes at which we flip between open via memory and open via disc
65    pub fn get_disc_threshold() -> u64 {
66        unsafe { bindings::vips_get_disc_threshold() }
67    }
68
69    /// Get the VIPS version as a static string, including a build date and time.
70    pub fn version_string() -> Result<String> {
71        unsafe {
72            let version = CStr::from_ptr(bindings::vips_version_string());
73            let version_str = version
74                .to_str()
75                .map_err(|_| Error::InitializationError("Error initializing string".to_string()))?;
76            Ok(version_str.to_string())
77        }
78    }
79
80    /// Free any thread-private data and flush any profiling information.
81    pub fn thread_shutdown() {
82        unsafe {
83            bindings::vips_thread_shutdown();
84        }
85    }
86
87    /// Get a pointer to the start of the error buffer as string
88    pub fn error_buffer() -> Result<String> {
89        unsafe {
90            let buffer = CStr::from_ptr(bindings::vips_error_buffer());
91            let buffer_str = buffer
92                .to_str()
93                .map_err(|_| Error::InitializationError("Error initializing string".to_string()))?;
94            Ok(buffer_str.to_string())
95        }
96    }
97
98    /// Format the string in the style of printf() and append to the error buffer.
99    pub fn error(domain: &str, error: &str) -> Result<()> {
100        unsafe {
101            let c_str_error = utils::new_c_string(error)?;
102            let c_str_domain = utils::new_c_string(domain)?;
103            bindings::vips_error(
104                c_str_domain.as_ptr(),
105                c_str_error.as_ptr(),
106            );
107            Ok(())
108        }
109    }
110
111    /// Format the string in the style of printf() and append to the error buffer. Then create and append a localised message based on the system error code, usually the value of errno
112    pub fn error_system(code: i32, domain: &str, error: &str) -> Result<()> {
113        unsafe {
114            let c_str_error = utils::new_c_string(error)?;
115            let c_str_domain = utils::new_c_string(domain)?;
116            bindings::vips_error_system(
117                code,
118                c_str_domain.as_ptr(),
119                c_str_error.as_ptr(),
120            );
121            Ok(())
122        }
123    }
124
125    /// Stop errors being logged. Use [func@error_thaw] to unfreeze
126    pub fn freeze_error_buffer() {
127        unsafe {
128            bindings::vips_error_freeze();
129        }
130    }
131
132    /// Clear and reset the error buffer.
133    pub fn error_clear() {
134        unsafe {
135            bindings::vips_error_clear();
136        }
137    }
138
139    /// Re-enable error logging.
140    pub fn error_thaw() {
141        unsafe {
142            bindings::vips_error_thaw();
143        }
144    }
145
146    /// Sends a formatted error message to stderr, then sends the contents of the error buffer, if any, then shuts down vips and terminates the program with an error code.
147    pub fn error_exit(error: &str) -> Result<()> {
148        unsafe {
149            let c_str_error = utils::new_c_string(error)?;
150            bindings::vips_error_exit(c_str_error.as_ptr());
151        }
152    }
153
154    /// Print the whole operation cache to stdout. Handy for debugging.
155    pub fn cache_print() {
156        unsafe {
157            bindings::vips_cache_print();
158        }
159    }
160
161    /// Set the maximum number of operations we keep in cache.
162    pub fn cache_set_max(max: i32) {
163        unsafe {
164            bindings::vips_cache_set_max(max);
165        }
166    }
167
168    /// Set the maximum amount of tracked memory we allow before we start dropping cached operations.
169    pub fn cache_set_max_mem(max: u64) {
170        unsafe {
171            bindings::vips_cache_set_max_mem(max);
172        }
173    }
174
175    /// Set the maximum number of tracked files we allow before we start dropping cached operations.
176    pub fn cache_set_max_files(max: i32) {
177        unsafe {
178            bindings::vips_cache_set_max_files(max);
179        }
180    }
181
182    /// Get the maximum number of operations we keep in cache.
183    pub fn cache_get_max() -> i32 {
184        unsafe { bindings::vips_cache_get_max() }
185    }
186
187    /// Get the maximum amount of tracked memory we allow before we start dropping cached operations.
188    pub fn cache_get_max_mem() -> u64 {
189        unsafe { bindings::vips_cache_get_max_mem() }
190    }
191
192    /// Get the maximum number of tracked files we allow before we start dropping cached operations.
193    pub fn cache_get_max_files() -> i32 {
194        unsafe { bindings::vips_cache_get_max_files() }
195    }
196
197    /// Get the current number of operations in cache.
198    pub fn cache_get_size() -> i32 {
199        unsafe { bindings::vips_cache_get_size() }
200    }
201
202    /// Handy for debugging. Print the operation cache to stdout just before exit.
203    pub fn cache_set_dump(flag: bool) {
204        unsafe {
205            bindings::vips_cache_set_dump(if flag { 1 } else { 0 });
206        }
207    }
208
209    /// Handy for debugging. Print operation cache actions to stdout as we run
210    pub fn cache_set_trace(flag: bool) {
211        unsafe {
212            bindings::vips_cache_set_trace(if flag { 1 } else { 0 });
213        }
214    }
215
216    /// set the number of worker threads for vips to operate
217    pub fn concurrency_set(max: i32) {
218        unsafe {
219            bindings::vips_concurrency_set(max);
220        }
221    }
222
223    /// get the number of worker threads that vips is operating
224    pub fn concurrency_get() -> i32 {
225        unsafe { bindings::vips_concurrency_get() }
226    }
227
228    /// Returns the number of bytes currently allocated via vips_malloc() and friends.
229    pub fn tracked_get_mem() -> u64 {
230        unsafe { bindings::vips_tracked_get_mem() }
231    }
232
233    /// Returns the largest number of bytes simultaneously allocated via vips_tracked_malloc().
234    pub fn tracked_get_mem_highwater() -> u64 {
235        unsafe { bindings::vips_tracked_get_mem_highwater() }
236    }
237
238    /// Returns the number of active allocations.
239    pub fn tracked_get_allocs() -> i32 {
240        unsafe { bindings::vips_tracked_get_allocs() }
241    }
242
243    /// Returns the number of open files.
244    pub fn tracked_get_files() -> i32 {
245        unsafe { bindings::vips_tracked_get_files() }
246    }
247
248    /// If a source does not support mmap or seek and the source is used with a loader that can only work from memory, then the data will be automatically read into memory to EOF before the loader starts.
249    pub fn pipe_read_limit_set(limit: i64) {
250        unsafe {
251            bindings::vips_pipe_read_limit_set(limit);
252        }
253    }
254
255    /// Call this to drop caches, close plugins, terminate background threads, and finalize any internal library testing.
256    /// vips_shutdown() is optional.
257    pub fn shutdown() {
258        unsafe {
259            bindings::vips_shutdown();
260        }
261    }
262}