magick_rust/lib.rs
1/*
2 * Copyright 2015-2017 Nathan Fiedler
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16//!
17//! "Safe" wrapper around the low-level bindings to ImageMagick.
18//!
19//! Prior to using the ImageMagick system, the application should invoke
20//! `magick_wand_genesis()`, which maps directly to `MagickWandGenesis`.
21//! Likewise, when an application is done using ImageMagick, invoke the
22//! `magick_wand_terminus()` function, which maps to `MagickWandTerminus`.
23//!
24
25// Make the Rust bindings compile cleanly, despite being very un-Rust-like
26// wrappers around C code.
27#![allow(dead_code)]
28#![allow(non_upper_case_globals)]
29#![allow(non_camel_case_types)]
30#![allow(non_snake_case)]
31
32use libc::size_t;
33use std::ffi::{CStr, CString};
34use std::slice::from_raw_parts;
35
36pub use crate::result::MagickError;
37use crate::result::Result;
38pub use crate::types::*;
39pub use crate::wand::*;
40
41mod conversions;
42mod result;
43mod types;
44mod wand;
45include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
46
47/// This function must be called before any other ImageMagick operations
48/// are attempted. This function is safe to be called repeatedly.
49pub fn magick_wand_genesis() {
50 unsafe {
51 if bindings::IsMagickWandInstantiated() == bindings::MagickBooleanType::MagickFalse {
52 bindings::MagickWandGenesis()
53 }
54 }
55}
56
57/// This function should be called when ImageMagick is no longer needed.
58/// This function is safe to be called repeatedly.
59pub fn magick_wand_terminus() {
60 unsafe {
61 if bindings::IsMagickWandInstantiated() == bindings::MagickBooleanType::MagickTrue {
62 bindings::MagickWandTerminus();
63 }
64 }
65}
66
67pub fn magick_query_fonts(pattern: &str) -> Result<Vec<String>> {
68 let mut number_fonts: size_t = 0;
69 let c_string = CString::new(pattern).map_err(|_| "could not convert to cstring")?;
70 let ptr =
71 unsafe { bindings::MagickQueryFonts(c_string.as_ptr(), &mut number_fonts as *mut size_t) };
72 if ptr.is_null() {
73 Err(MagickError(
74 "null ptr returned by magick_query_fonts".to_string(),
75 ))
76 } else {
77 let mut v = Vec::new();
78 let c_str_ptr_slice = unsafe { from_raw_parts(ptr, number_fonts as usize) };
79 for c_str_ptr in c_str_ptr_slice {
80 let c_str = unsafe { CStr::from_ptr(*c_str_ptr) };
81 v.push(c_str.to_string_lossy().into_owned())
82 }
83 Ok(v)
84 }
85}