1#![allow(non_upper_case_globals)]
3#![allow(non_camel_case_types)]
4#![allow(non_snake_case)]
5#![allow(improper_ctypes)]
6#![allow(dead_code)]
7#[macro_use]
8extern crate num_derive;
9extern crate num_traits;
10
11pub mod bindings;
12pub mod error;
13mod image;
14pub mod ops;
15mod utils;
16
17use error::Error;
18use std::ffi::*;
19
20pub use image::*;
21
22pub type Result<T> = std::result::Result<T, error::Error>;
23
24pub struct VipsApp;
25
26impl VipsApp {
28 pub fn default(name: &str) -> Result<VipsApp> {
30 init(
31 name, false,
32 )?;
33 Ok(VipsApp)
34 }
35
36 pub fn new(name: &str, detect_leak: bool) -> Result<VipsApp> {
38 init(
39 name,
40 detect_leak,
41 )?;
42 Ok(VipsApp)
43 }
44
45 pub fn progress_set(&self, flag: bool) {
46 unsafe {
47 bindings::vips_progress_set(if flag { 1 } else { 0 });
48 }
49 }
50
51 pub fn get_disc_threshold(&self) -> u64 {
52 unsafe { bindings::vips_get_disc_threshold() }
53 }
54
55 pub fn version_string(&self) -> Result<&str> {
56 unsafe {
57 let version = CStr::from_ptr(bindings::vips_version_string());
58 version
59 .to_str()
60 .map_err(|_| Error::InitializationError("Error initializing string"))
61 }
62 }
63
64 pub fn thread_shutdown(&self) {
65 unsafe {
66 bindings::vips_thread_shutdown();
67 }
68 }
69
70 pub fn error_buffer(&self) -> Result<&str> {
71 unsafe {
72 let buffer = CStr::from_ptr(bindings::vips_error_buffer());
73 buffer
74 .to_str()
75 .map_err(|_| Error::InitializationError("Error initializing string"))
76 }
77 }
78
79 pub fn error(&self, domain: &str, error: &str) -> Result<()> {
80 unsafe {
81 let c_str_error = utils::new_c_string(error)?;
82 let c_str_domain = utils::new_c_string(domain)?;
83 bindings::vips_error(
84 c_str_domain.as_ptr(),
85 c_str_error.as_ptr(),
86 );
87 Ok(())
88 }
89 }
90
91 pub fn error_system(&self, code: i32, domain: &str, error: &str) -> Result<()> {
92 unsafe {
93 let c_str_error = utils::new_c_string(error)?;
94 let c_str_domain = utils::new_c_string(domain)?;
95 bindings::vips_error_system(
96 code,
97 c_str_domain.as_ptr(),
98 c_str_error.as_ptr(),
99 );
100 Ok(())
101 }
102 }
103
104 pub fn freeze_error_buffer(&self) {
105 unsafe {
106 bindings::vips_error_freeze();
107 }
108 }
109
110 pub fn error_clear(&self) {
111 unsafe {
112 bindings::vips_error_clear();
113 }
114 }
115
116 pub fn error_thaw(&self) {
117 unsafe {
118 bindings::vips_error_thaw();
119 }
120 }
121
122 pub fn error_exit(&self, error: &str) -> Result<()> {
123 unsafe {
124 let c_str_error = utils::new_c_string(error)?;
125 bindings::vips_error_exit(c_str_error.as_ptr());
126 }
127 }
128
129 pub fn cache_print(&self) {
130 unsafe {
131 bindings::vips_cache_print();
132 }
133 }
134
135 pub fn cache_set_max(&self, max: i32) {
136 unsafe {
137 bindings::vips_cache_set_max(max);
138 }
139 }
140
141 pub fn cache_set_max_mem(&self, max: u64) {
142 unsafe {
143 bindings::vips_cache_set_max_mem(max);
144 }
145 }
146
147 pub fn cache_get_max(&self) -> i32 {
148 unsafe { bindings::vips_cache_get_max() }
149 }
150
151 pub fn cache_get_max_mem(&self) -> u64 {
152 unsafe { bindings::vips_cache_get_max_mem() }
153 }
154
155 pub fn cache_get_size(&self) -> i32 {
156 unsafe { bindings::vips_cache_get_size() }
157 }
158
159 pub fn cache_set_max_files(&self, max: i32) {
160 unsafe {
161 bindings::vips_cache_set_max_files(max);
162 }
163 }
164
165 pub fn cache_get_max_files(&self) -> i32 {
166 unsafe { bindings::vips_cache_get_max_files() }
167 }
168
169 pub fn vips_cache_set_dump(&self, flag: bool) {
170 unsafe {
171 bindings::vips_cache_set_dump(if flag { 1 } else { 0 });
172 }
173 }
174
175 pub fn vips_cache_set_trace(&self, flag: bool) {
176 unsafe {
177 bindings::vips_cache_set_trace(if flag { 1 } else { 0 });
178 }
179 }
180
181 pub fn concurrency_set(&self, max: i32) {
183 unsafe {
184 bindings::vips_concurrency_set(max);
185 }
186 }
187
188 pub fn concurrency_get(&self) -> i32 {
190 unsafe { bindings::vips_concurrency_get() }
191 }
192
193 pub fn tracked_get_mem(&self) -> u64 {
194 unsafe { bindings::vips_tracked_get_mem() }
195 }
196
197 pub fn tracked_get_mem_highwater(&self) -> u64 {
198 unsafe { bindings::vips_tracked_get_mem_highwater() }
199 }
200
201 pub fn tracked_get_allocs(&self) -> i32 {
202 unsafe { bindings::vips_tracked_get_allocs() }
203 }
204
205 pub fn pipe_read_limit_set(&self, limit: i64) {
206 unsafe {
207 bindings::vips_pipe_read_limit_set(limit);
208 }
209 }
210}
211
212impl Drop for VipsApp {
213 fn drop(&mut self) {
214 unsafe {
215 bindings::vips_shutdown();
216 }
217 }
218}
219
220fn init(name: &str, detect_leak: bool) -> Result<i32> {
221 let cstring = utils::new_c_string(name);
222 if let Ok(c_name) = cstring {
223 let res = unsafe { bindings::vips_init(c_name.as_ptr()) };
224 let result = if res == 0 {
225 Ok(res)
226 } else {
227 Err(Error::InitializationError("Failed to init libvips"))
228 };
229 unsafe {
230 if detect_leak {
231 bindings::vips_leak_set(1);
232 };
233 }
234 result
235 } else {
236 Err(Error::InitializationError("Failed to convert rust string to C string"))
237 }
238}