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}