Merge branch 'master' into main
This commit is contained in:
commit
11da380e1b
|
@ -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]
|
||||
|
|
45
build.rs
45
build.rs
|
@ -24,9 +24,17 @@ use std::path::{Path, PathBuf};
|
|||
use std::process::Command;
|
||||
|
||||
const MIN_VERSION: &'static str = "7.0";
|
||||
const MAX_VERSION: &'static str = "7.1";
|
||||
const MAX_VERSION: &'static str = "7.2";
|
||||
|
||||
static HEADER: &'static str = "#include <MagickWand/MagickWand.h>\n";
|
||||
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") {
|
||||
|
@ -41,14 +49,14 @@ fn main() {
|
|||
env_var_set_default("IMAGE_MAGICK_LIBS", "MagickWand-7");
|
||||
}
|
||||
|
||||
let cppflags = Command::new("MagickCore-config")
|
||||
.arg("--cppflags")
|
||||
.output()
|
||||
.unwrap()
|
||||
.stdout;
|
||||
let cppflags = String::from_utf8(cppflags).unwrap();
|
||||
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);
|
||||
env_var_set_default("BINDGEN_EXTRA_CLANG_ARGS", &cppflags);
|
||||
}
|
||||
|
||||
let lib_dirs = find_image_magick_lib_dirs();
|
||||
for d in &lib_dirs {
|
||||
|
@ -75,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()]
|
||||
|
@ -172,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")
|
||||
|
@ -181,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)
|
||||
|
@ -258,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).
|
||||
|
|
|
@ -4,9 +4,9 @@ RUN apt-get update \
|
|||
&& apt-get -y install curl build-essential clang pkg-config libjpeg-turbo-progs libpng-dev \
|
||||
&& rm -rfv /var/lib/apt/lists/*
|
||||
|
||||
ENV MAGICK_VERSION 7.0
|
||||
ENV MAGICK_VERSION 7.1
|
||||
|
||||
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 \
|
||||
|
@ -16,6 +16,8 @@ RUN curl https://www.imagemagick.org/download/ImageMagick.tar.gz | tar xz \
|
|||
|
||||
RUN adduser --disabled-password --gecos '' magick-rust
|
||||
|
||||
ADD policy.xml /usr/local/lib/ImageMagick-7.0.11/config-Q16HDRI/policy.xml
|
||||
|
||||
USER magick-rust
|
||||
|
||||
ENV USER=magick-rust LD_LIBRARY_PATH=/usr/local/lib
|
||||
|
|
34
docker/Dockerfile.docs
Normal file
34
docker/Dockerfile.docs
Normal file
|
@ -0,0 +1,34 @@
|
|||
FROM rust:latest as builder
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get -y install curl build-essential clang pkg-config libjpeg-turbo-progs libpng-dev \
|
||||
&& rm -rfv /var/lib/apt/lists/*
|
||||
|
||||
ENV MAGICK_VERSION 7.0
|
||||
|
||||
RUN curl https://www.imagemagick.org/download/ImageMagick.tar.gz | tar xz \
|
||||
&& cd ImageMagick-${MAGICK_VERSION}* \
|
||||
&& ./configure --with-magick-plus-plus=no --with-perl=no \
|
||||
&& make \
|
||||
&& make install \
|
||||
&& cd .. \
|
||||
&& rm -r ImageMagick-${MAGICK_VERSION}*
|
||||
|
||||
RUN adduser --disabled-password --gecos '' magick-rust \
|
||||
&& mkdir /src \
|
||||
&& chown magick-rust:magick-rust /src
|
||||
|
||||
USER magick-rust
|
||||
|
||||
ENV USER=magick-rust LD_LIBRARY_PATH=/usr/local/lib
|
||||
|
||||
WORKDIR /src
|
||||
|
||||
COPY --chown=magick-rust:magick-rust Cargo.toml Cargo.lock build.rs ./
|
||||
COPY --chown=magick-rust:magick-rust ./src ./src
|
||||
|
||||
RUN cargo doc --no-deps
|
||||
|
||||
FROM arm64v8/nginx:mainline-alpine
|
||||
|
||||
COPY --from=builder --chown=nginx:nginx /src/target/doc /usr/share/nginx/html
|
|
@ -9,3 +9,8 @@ services:
|
|||
- ..:/src
|
||||
stdin_open: true
|
||||
tty: true
|
||||
|
||||
magick-docs:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: docker/Dockerfile.docs
|
||||
|
|
20
docker/policy.xml
Normal file
20
docker/policy.xml
Normal file
|
@ -0,0 +1,20 @@
|
|||
<policymap>
|
||||
<policy domain="resource" name="memory" value="256MiB" />
|
||||
<policy domain="resource" name="list-length" value="32" />
|
||||
<policy domain="resource" name="width" value="10KP" />
|
||||
<policy domain="resource" name="height" value="10KP" />
|
||||
<policy domain="resource" name="map" value="512MiB" />
|
||||
<policy domain="resource" name="area" value="16KP" />
|
||||
<policy domain="resource" name="disk" value="1GiB" />
|
||||
<policy domain="resource" name="file" value="768" />
|
||||
<policy domain="resource" name="thread" value="2" />
|
||||
<policy domain="coder" rights="none" pattern="*" />
|
||||
<policy domain="coder" rights="read | write" pattern="{GIF,JPEG,PNG,WEBP}" />
|
||||
<policy domain="filter" rights="none" pattern="*" />
|
||||
<policy domain="path" rights="none" pattern="@*" />
|
||||
<policy domain="delegate" rights="none" pattern="*" />
|
||||
<policy domain="module" rights="none" pattern="*" />
|
||||
<policy domain="module" rights="read | write" pattern="{GIF,JPEG,PNG,WEBP}" />
|
||||
<!-- indirect reads not permitted -->
|
||||
<policy domain="system" name="precision" value="6" />
|
||||
</policymap>
|
|
@ -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();
|
||||
|
@ -267,21 +297,21 @@ impl MagickWand {
|
|||
|
||||
// Define two 'quantum_range' functions because the bindings::QuantumRange symbol
|
||||
// is not available if hdri is disabled in the compiled ImageMagick libs
|
||||
#[cfg(not(feature="disable-hdri"))]
|
||||
#[cfg(not(feature = "disable-hdri"))]
|
||||
fn quantum_range(&self) -> Result<f64, &'static str> {
|
||||
return Ok(bindings::QuantumRange);
|
||||
}
|
||||
|
||||
// with disable-hdri enabled we define our own quantum_range
|
||||
// values lifted directly from magick-type.h
|
||||
#[cfg(feature="disable-hdri")]
|
||||
#[cfg(feature = "disable-hdri")]
|
||||
fn quantum_range(&self) -> Result<f64, &'static str> {
|
||||
match bindings::MAGICKCORE_QUANTUM_DEPTH {
|
||||
8 => Ok(255.0f64),
|
||||
16 => Ok(65535.0f64),
|
||||
32 => Ok(4294967295.0f64),
|
||||
64 => Ok(18446744073709551615.0f64),
|
||||
_ => Err("Quantum depth must be one of 8, 16, 32 or 64")
|
||||
_ => Err("Quantum depth must be one of 8, 16, 32 or 64"),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -309,7 +339,6 @@ impl MagickWand {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/// Extend the image as defined by the geometry, gravity, and wand background color. Set the
|
||||
/// (x,y) offset of the geometry to move the original wand relative to the extended wand.
|
||||
pub fn extend_image(
|
||||
|
@ -702,20 +731,31 @@ impl MagickWand {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/// Rescale the image using seam carving algorithm
|
||||
pub fn liquid_rescale_image(&self, width: usize, height: usize, delta_x: f64, rigidity: f64) -> Result<(), &'static str> {
|
||||
match unsafe { bindings::MagickLiquidRescaleImage(self.wand, width, height, delta_x, rigidity) } {
|
||||
pub fn liquid_rescale_image(
|
||||
&self,
|
||||
width: usize,
|
||||
height: usize,
|
||||
delta_x: f64,
|
||||
rigidity: f64,
|
||||
) -> Result<(), &'static str> {
|
||||
match unsafe {
|
||||
bindings::MagickLiquidRescaleImage(self.wand, width, height, delta_x, rigidity)
|
||||
} {
|
||||
bindings::MagickBooleanType_MagickTrue => Ok(()),
|
||||
_ => Err("failed to liquid-rescale image")
|
||||
_ => Err("failed to liquid-rescale image"),
|
||||
}
|
||||
}
|
||||
|
||||
/// Implodes the image towards the center by the specified percentage
|
||||
pub fn implode(&self, amount: f64, method: bindings::PixelInterpolateMethod) -> Result<(), &'static str> {
|
||||
pub fn implode(
|
||||
&self,
|
||||
amount: f64,
|
||||
method: bindings::PixelInterpolateMethod,
|
||||
) -> Result<(), &'static str> {
|
||||
match unsafe { bindings::MagickImplodeImage(self.wand, amount, method) } {
|
||||
bindings::MagickBooleanType_MagickTrue => Ok(()),
|
||||
_ => Err("failed to implode image")
|
||||
_ => Err("failed to implode image"),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -830,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)
|
||||
|
@ -846,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);
|
||||
|
|
|
@ -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};
|
||||
|
|
12
tests/lib.rs
12
tests/lib.rs
|
@ -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());
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue