This commit is contained in:
asonix 2021-06-19 12:45:24 -05:00
commit 530b745181
6 changed files with 77 additions and 11 deletions

View file

@ -14,7 +14,7 @@ build = "build.rs"
libc = "0.2.70"
[build-dependencies]
bindgen = "0.53.2"
bindgen = "0.56.0"
pkg-config = "0.3.17"
[features]

View file

@ -30,6 +30,12 @@ static HEADER: &'static str = r#"#define MAGICKCORE_QUANTUM_DEPTH 16
#include <MagickWand/MagickWand.h>
"#;
//on windows path env always contain : like c:
pub const PATH_SEPARATOR: &str = match cfg!(target_os = "windows") {
true => ";",
_ => ":",
};
fn main() {
if cfg!(target_os = "freebsd") {
// pkg_config does not seem to work properly on FreeBSD, so
@ -43,6 +49,15 @@ fn main() {
env_var_set_default("IMAGE_MAGICK_LIBS", "MagickWand-7");
}
let check_cppflags = Command::new("MagickCore-config").arg("--cppflags").output();
//on windows can not exec
if check_cppflags.is_ok() {
let cppflags = check_cppflags.unwrap().stdout;
let cppflags = String::from_utf8(cppflags).unwrap();
env_var_set_default("BINDGEN_EXTRA_CLANG_ARGS", &cppflags);
}
let lib_dirs = find_image_magick_lib_dirs();
for d in &lib_dirs {
if !d.exists() {
@ -68,7 +83,7 @@ fn main() {
let target = env::var("TARGET").unwrap();
let libs_env = env::var("IMAGE_MAGICK_LIBS").ok();
let libs = match libs_env {
Some(ref v) => v.split(":").map(|x| x.to_owned()).collect(),
Some(ref v) => v.split(PATH_SEPARATOR).map(|x| x.to_owned()).collect(),
None => {
if target.contains("windows") {
vec!["CORE_RL_MagickWand_".to_string()]
@ -165,7 +180,11 @@ fn env_var_set_default(name: &str, value: &str) {
fn find_image_magick_lib_dirs() -> Vec<PathBuf> {
println!("cargo:rerun-if-env-changed=IMAGE_MAGICK_LIB_DIRS");
env::var("IMAGE_MAGICK_LIB_DIRS")
.map(|x| x.split(":").map(PathBuf::from).collect::<Vec<PathBuf>>())
.map(|x| {
x.split(PATH_SEPARATOR)
.map(PathBuf::from)
.collect::<Vec<PathBuf>>()
})
.or_else(|_| Ok(vec![find_image_magick_dir()?.join("lib")]))
.or_else(|_: env::VarError| -> Result<_, env::VarError> { Ok(run_pkg_config().link_paths) })
.expect("Couldn't find ImageMagick library directory")
@ -174,7 +193,11 @@ fn find_image_magick_lib_dirs() -> Vec<PathBuf> {
fn find_image_magick_include_dirs() -> Vec<PathBuf> {
println!("cargo:rerun-if-env-changed=IMAGE_MAGICK_INCLUDE_DIRS");
env::var("IMAGE_MAGICK_INCLUDE_DIRS")
.map(|x| x.split(":").map(PathBuf::from).collect::<Vec<PathBuf>>())
.map(|x| {
x.split(PATH_SEPARATOR)
.map(PathBuf::from)
.collect::<Vec<PathBuf>>()
})
.or_else(|_| Ok(vec![find_image_magick_dir()?.join("include")]))
.or_else(|_: env::VarError| -> Result<_, env::VarError> {
Ok(run_pkg_config().include_paths)
@ -251,10 +274,7 @@ fn run_pkg_config() -> pkg_config::Library {
.unwrap()
.success()
{
panic!(format!(
"MagickWand version must be no higher than {}",
MAX_VERSION
));
panic!("MagickWand version must be less than 7.1");
}
// We have to split the version check and the cflags/libs check because
// you can't do both at the same time on RHEL (apparently).

View file

@ -6,7 +6,7 @@ RUN apt-get update \
ENV MAGICK_VERSION 7.0
RUN curl https://www.imagemagick.org/download/ImageMagick.tar.gz | tar xz \
RUN curl https://download.imagemagick.org/ImageMagick/download/ImageMagick.tar.gz | tar xz \
&& cd ImageMagick-${MAGICK_VERSION}* \
&& ./configure --with-magick-plus-plus=no --with-perl=no \
&& make \

View file

@ -37,6 +37,23 @@ wand_common!(
MagickGetException
);
/// Resource type to use with [set_resource_limit](MagickWand::set_resource_limit)
#[derive(Debug, Clone, Copy)]
pub enum ResourceType {
Undefined = bindings::ResourceType_UndefinedResource as isize,
Area = bindings::ResourceType_AreaResource as isize,
Disk = bindings::ResourceType_DiskResource as isize,
File = bindings::ResourceType_FileResource as isize,
Height = bindings::ResourceType_HeightResource as isize,
Map = bindings::ResourceType_MapResource as isize,
Memory = bindings::ResourceType_MemoryResource as isize,
Thread = bindings::ResourceType_ThreadResource as isize,
Throttle = bindings::ResourceType_ThrottleResource as isize,
Time = bindings::ResourceType_TimeResource as isize,
Width = bindings::ResourceType_WidthResource as isize,
ListLength = bindings::ResourceType_ListLengthResource as isize,
}
/// MagickWand is a Rustic wrapper to the Rust bindings to ImageMagick.
///
/// Instantiating a `MagickWand` will construct an ImageMagick "wand"
@ -56,6 +73,19 @@ impl MagickWand {
}
}
pub fn set_resource_limit(resource: ResourceType, limit: u64) -> Result<(), &'static str> {
let result = unsafe {
bindings::SetMagickResourceLimit(
resource as bindings::ResourceType,
limit as bindings::MagickSizeType,
)
};
match result {
bindings::MagickBooleanType_MagickTrue => Ok(()),
_ => Err("failed to set resource limit"),
}
}
pub fn set_option(&mut self, key: &str, value: &str) -> Result<(), &'static str> {
let c_key = CString::new(key).unwrap();
let c_value = CString::new(value).unwrap();
@ -840,6 +870,9 @@ impl MagickWand {
// Sets the image to the specified alpha level.
MagickSetImageAlpha => set_image_alpha(alpha: f64)
// Control the brightness, saturation, and hue of an image
MagickModulateImage => modulate_image(brightness: f64, saturation: f64, hue: f64)
/// Set the image alpha channel mode.
MagickSetImageAlphaChannel => set_image_alpha_channel(
alpha_channel: bindings::AlphaChannelOption)
@ -856,6 +889,9 @@ impl MagickWand {
/// Discard all but one of any pixel color.
MagickUniqueImageColors => unique_image_colors()
/// Applies k-means color reduction to the image.
MagickKmeansImage => kmeans(number_colors: size_t, max_iterations: size_t, tolerance: f64)
);
get!(get_image_colors, MagickGetImageColors, size_t);

View file

@ -20,5 +20,5 @@ mod magick;
mod pixel;
pub use self::drawing::DrawingWand;
pub use self::magick::MagickWand;
pub use self::magick::{MagickWand, ResourceType};
pub use self::pixel::{PixelWand, HSL};

View file

@ -16,7 +16,7 @@
extern crate magick_rust;
use magick_rust::{bindings, magick_wand_genesis, MagickWand, PixelWand};
use magick_rust::{bindings, magick_wand_genesis, MagickWand, PixelWand, ResourceType};
use magick_rust::ToMagick;
use std::error::Error;
@ -361,3 +361,13 @@ fn test_negate_image() {
pixel_color.get_color_as_string().unwrap()
);
}
#[test]
fn test_resource_limits() {
START.call_once(|| {
magick_wand_genesis();
});
MagickWand::set_resource_limit(ResourceType::Thread, 1).unwrap();
let wand = MagickWand::new();
assert!(wand.read_image("tests/data/rust.png").is_ok());
}