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