feat: std error compatible error

This commit is contained in:
DCjanus
2021-12-25 02:41:45 +08:00
parent 679ccc43fa
commit 409a583b22
8 changed files with 210 additions and 191 deletions

View File

@ -13,13 +13,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
use bindings;
use std::ffi::{CStr, CString};
use std::fmt;
#[cfg(target_os = "freebsd")]
use libc::size_t;
#[cfg(not(target_os = "freebsd"))]
use size_t;
use std::ffi::{CStr, CString};
use std::fmt;
use bindings;
use crate::result::MagickError;
use crate::result::Result;
wand_common!(
DrawingWand,
@ -34,7 +39,7 @@ wand_common!(
);
impl DrawingWand {
pub fn draw_annotation(&mut self, x: f64, y: f64, text: &str) -> Result<(), &'static str> {
pub fn draw_annotation(&mut self, x: f64, y: f64, text: &str) -> Result<()> {
let c_string = CString::new(text).map_err(|_| "could not convert to cstring")?;
unsafe { bindings::DrawAnnotation(self.wand, x, y, c_string.as_ptr() as *const _) };
Ok(())

View File

@ -37,10 +37,14 @@ macro_rules! wand_common {
unsafe { ::bindings::$clear_wand(self.wand) }
}
pub fn clear_exception(&mut self) -> Result<(), &'static str> {
pub fn clear_exception(&mut self) -> Result<()> {
match unsafe { ::bindings::$clear_exc(self.wand) } {
::bindings::MagickBooleanType_MagickTrue => Ok(()),
_ => Err(concat!("failed to clear", stringify!($wand), "exception")),
_ => Err(MagickError(concat!(
"failed to clear",
stringify!($wand),
"exception"
))),
}
}
@ -48,29 +52,27 @@ macro_rules! wand_common {
unsafe { ::bindings::$get_exc_type(self.wand) }
}
pub fn get_exception(
&self,
) -> Result<(String, ::bindings::ExceptionType), &'static str> {
pub fn get_exception(&self) -> Result<(String, ::bindings::ExceptionType)> {
let mut severity: ::bindings::ExceptionType =
::bindings::ExceptionType_UndefinedException;
// TODO: memory management
let ptr = unsafe { ::bindings::$get_exc(self.wand, &mut severity as *mut _) };
if ptr.is_null() {
Err(concat!(
Err(MagickError(concat!(
"null ptr returned by",
stringify!($wand),
"get_exception"
))
)))
} else {
let c_str = unsafe { CStr::from_ptr(ptr) };
Ok((c_str.to_string_lossy().into_owned(), severity))
}
}
pub fn is_wand(&self) -> Result<(), &'static str> {
pub fn is_wand(&self) -> Result<()> {
match unsafe { ::bindings::$is_wand(self.wand) } {
::bindings::MagickBooleanType_MagickTrue => Ok(()),
_ => Err(concat!(stringify!($wand), " not a wand")),
_ => Err(MagickError(concat!(stringify!($wand), " not a wand"))),
}
}
}
@ -110,10 +112,10 @@ macro_rules! set_get {
pub fn $get(&self) -> $typ {
unsafe { ::bindings::$c_get(self.wand) }
}
pub fn $set(&mut self, v: $typ) -> Result<(), &'static str> {
pub fn $set(&mut self, v: $typ) -> Result<()> {
match unsafe { ::bindings::$c_set(self.wand, v) } {
::bindings::MagickBooleanType_MagickTrue => Ok(()),
_ => Err(concat!(stringify!($set), " returned false"))
_ => Err(MagickError(concat!(stringify!($set), " returned false")))
}
}
)*
@ -143,10 +145,13 @@ macro_rules! set_get_unchecked {
macro_rules! string_get {
($get:ident, $c_get:ident) => {
pub fn $get(&self) -> Result<String, &'static str> {
pub fn $get(&self) -> Result<String> {
let ptr = unsafe { ::bindings::$c_get(self.wand) };
if ptr.is_null() {
Err(concat!("null ptr returned by ", stringify!($get)))
Err(MagickError(concat!(
"null ptr returned by ",
stringify!($get)
)))
} else {
let c_str = unsafe { ::std::ffi::CStr::from_ptr(ptr) };
let result: String = c_str.to_string_lossy().into_owned();
@ -161,11 +166,11 @@ macro_rules! string_set_get {
($($get:ident, $set:ident, $c_get:ident, $c_set:ident)*) => {
$(
string_get!($get, $c_get);
pub fn $set(&mut self, s: &str) -> Result<(), &'static str> {
pub fn $set(&mut self, s: &str) -> Result<()> {
let c_string = std::ffi::CString::new(s).map_err(|_| "could not convert to cstring")?;
match unsafe { ::bindings::$c_set(self.wand, c_string.as_ptr()) } {
::bindings::MagickBooleanType_MagickTrue => Ok(()),
_ => Err(concat!(stringify!($set), " returned false"))
_ => Err(MagickError(concat!(stringify!($set), " returned false")))
}
}
)*
@ -180,7 +185,7 @@ macro_rules! string_set_get_unchecked {
($($get:ident, $set:ident, $c_get:ident, $c_set:ident )*) => {
$(
string_get!($get, $c_get);
pub fn $set(&mut self, s: &str) -> Result<(), &'static str> {
pub fn $set(&mut self, s: &str) -> Result<()> {
let c_string = ::std::ffi::CString::new(s).map_err(|_| "could not convert to cstring")?;
unsafe { ::bindings::$c_set(self.wand, c_string.as_ptr()) };
Ok(())
@ -252,10 +257,10 @@ macro_rules! mutations {
($($(#[$attr:meta])* $c_fun:ident => $fun:ident($($arg:ident: $ty:ty),*))*) => {
$(
$(#[$attr])*
pub fn $fun(&self $(, $arg: $ty)*) -> Result<(), &'static str> {
pub fn $fun(&self $(, $arg: $ty)*) -> Result<()> {
match unsafe { bindings::$c_fun(self.wand $(, $arg)*) } {
bindings::MagickBooleanType_MagickTrue => Ok(()),
_ => Err(concat!(stringify!($c_fun), " invocation failed"))
_ => Err(MagickError(concat!(stringify!($c_fun), " invocation failed")))
}
}
)*

View File

@ -13,18 +13,23 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
use libc::c_void;
use std::ffi::{CStr, CString};
use std::{fmt, ptr, slice};
use super::{DrawingWand, PixelWand};
use bindings;
use conversions::*;
use libc::c_void;
#[cfg(target_os = "freebsd")]
use libc::{size_t, ssize_t};
use bindings;
use conversions::*;
use result::MagickError;
#[cfg(not(target_os = "freebsd"))]
use {size_t, ssize_t};
use crate::result::Result;
use super::{DrawingWand, PixelWand};
wand_common!(
MagickWand,
NewMagickWand,
@ -61,19 +66,14 @@ pub enum ResourceType {
/// When the `MagickWand` is dropped, the ImageMagick wand will be
/// destroyed as well.
impl MagickWand {
pub fn new_image(
&self,
columns: size_t,
rows: size_t,
pixel_wand: &PixelWand,
) -> Result<(), &'static str> {
pub fn new_image(&self, columns: size_t, rows: size_t, pixel_wand: &PixelWand) -> Result<()> {
match unsafe { bindings::MagickNewImage(self.wand, columns, rows, pixel_wand.wand) } {
bindings::MagickBooleanType_MagickTrue => Ok(()),
_ => Err("Could not create image"),
_ => Err(MagickError("Could not create image")),
}
}
pub fn set_resource_limit(resource: ResourceType, limit: u64) -> Result<(), &'static str> {
pub fn set_resource_limit(resource: ResourceType, limit: u64) -> Result<()> {
let result = unsafe {
bindings::SetMagickResourceLimit(
resource as bindings::ResourceType,
@ -82,18 +82,18 @@ impl MagickWand {
};
match result {
bindings::MagickBooleanType_MagickTrue => Ok(()),
_ => Err("failed to set resource limit"),
_ => Err(MagickError("failed to set resource limit")),
}
}
pub fn set_option(&mut self, key: &str, value: &str) -> Result<(), &'static str> {
pub fn set_option(&mut self, key: &str, value: &str) -> Result<()> {
let c_key = CString::new(key).unwrap();
let c_value = CString::new(value).unwrap();
let result =
unsafe { bindings::MagickSetOption(self.wand, c_key.as_ptr(), c_value.as_ptr()) };
match result {
bindings::MagickBooleanType_MagickTrue => Ok(()),
_ => Err("failed to set option"),
_ => Err(MagickError("failed to set option")),
}
}
@ -104,7 +104,7 @@ impl MagickWand {
y: f64,
angle: f64,
text: &str,
) -> Result<(), &'static str> {
) -> Result<()> {
let c_string = CString::new(text).map_err(|_| "could not convert to cstring")?;
match unsafe {
bindings::MagickAnnotateImage(
@ -117,15 +117,15 @@ impl MagickWand {
)
} {
bindings::MagickBooleanType_MagickTrue => Ok(()),
_ => Err("unable to annotate image"),
_ => Err(MagickError("unable to annotate image")),
}
}
/// Add all images from another wand to this wand at the current index.
pub fn add_image(&mut self, other_wand: &MagickWand) -> Result<(), &'static str> {
pub fn add_image(&mut self, other_wand: &MagickWand) -> Result<()> {
match unsafe { bindings::MagickAddImage(self.wand, other_wand.wand) } {
bindings::MagickBooleanType_MagickTrue => Ok(()),
_ => Err("unable to add images from another wand"),
_ => Err(MagickError("unable to add images from another wand")),
}
}
@ -136,37 +136,37 @@ impl MagickWand {
}
}
pub fn label_image(&self, label: &str) -> Result<(), &'static str> {
pub fn label_image(&self, label: &str) -> Result<()> {
let c_label = CString::new(label).unwrap();
let result = unsafe { bindings::MagickLabelImage(self.wand, c_label.as_ptr()) };
match result {
bindings::MagickBooleanType_MagickTrue => Ok(()),
_ => Err("failed to add label"),
_ => Err(MagickError("failed to add label")),
}
}
pub fn write_images(&self, path: &str, adjoin: bool) -> Result<(), &'static str> {
pub fn write_images(&self, path: &str, adjoin: bool) -> Result<()> {
let c_name = CString::new(path).unwrap();
let result =
unsafe { bindings::MagickWriteImages(self.wand, c_name.as_ptr(), adjoin.to_magick()) };
match result {
bindings::MagickBooleanType_MagickTrue => Ok(()),
_ => Err("failed to write images"),
_ => Err(MagickError("failed to write images")),
}
}
/// Read the image data from the named file.
pub fn read_image(&self, path: &str) -> Result<(), &'static str> {
pub fn read_image(&self, path: &str) -> Result<()> {
let c_name = CString::new(path).unwrap();
let result = unsafe { bindings::MagickReadImage(self.wand, c_name.as_ptr()) };
match result {
bindings::MagickBooleanType_MagickTrue => Ok(()),
_ => Err("failed to read image"),
_ => Err(MagickError("failed to read image")),
}
}
/// Read the image data from the vector of bytes.
pub fn read_image_blob<T: AsRef<[u8]>>(&self, data: T) -> Result<(), &'static str> {
pub fn read_image_blob<T: AsRef<[u8]>>(&self, data: T) -> Result<()> {
let int_slice = data.as_ref();
let size = int_slice.len();
let result = unsafe {
@ -178,24 +178,24 @@ impl MagickWand {
};
match result {
bindings::MagickBooleanType_MagickTrue => Ok(()),
_ => Err("failed to read image"),
_ => Err(MagickError("failed to read image")),
}
}
/// Same as read_image, but reads only the width, height, size and format of an image,
/// without reading data.
pub fn ping_image(&self, path: &str) -> Result<(), &'static str> {
pub fn ping_image(&self, path: &str) -> Result<()> {
let c_name = CString::new(path).unwrap();
let result = unsafe { bindings::MagickPingImage(self.wand, c_name.as_ptr()) };
match result {
bindings::MagickBooleanType_MagickTrue => Ok(()),
_ => Err("failed to ping image"),
_ => Err(MagickError("failed to ping image")),
}
}
/// Same as read_image, but reads only the width, height, size and format of an image,
/// without reading data.
pub fn ping_image_blob<T: AsRef<[u8]>>(&self, data: T) -> Result<(), &'static str> {
pub fn ping_image_blob<T: AsRef<[u8]>>(&self, data: T) -> Result<()> {
let int_slice = data.as_ref();
let size = int_slice.len();
let result = unsafe {
@ -207,7 +207,7 @@ impl MagickWand {
};
match result {
bindings::MagickBooleanType_MagickTrue => Ok(()),
_ => Err("failed to ping image"),
_ => Err(MagickError("failed to ping image")),
}
}
@ -238,7 +238,7 @@ impl MagickWand {
clip_to_self: bool,
x: isize,
y: isize,
) -> Result<(), &'static str> {
) -> Result<()> {
let native_clip_to_self = if clip_to_self {
bindings::MagickBooleanType_MagickTrue
} else {
@ -256,7 +256,7 @@ impl MagickWand {
};
match result {
bindings::MagickBooleanType_MagickTrue => Ok(()),
_ => Err("failed to compose images"),
_ => Err(MagickError("failed to compose images")),
}
}
@ -265,19 +265,23 @@ impl MagickWand {
&self,
clut_wand: &MagickWand,
method: bindings::PixelInterpolateMethod,
) -> Result<(), &'static str> {
) -> Result<()> {
let result = unsafe { bindings::MagickClutImage(self.wand, clut_wand.wand, method) };
match result {
bindings::MagickBooleanType_MagickTrue => Ok(()),
_ => Err("failed to replace colors in the image from color lookup table"),
_ => Err(MagickError(
"failed to replace colors in the image from color lookup table",
)),
}
}
pub fn hald_clut_image(&self, clut_wand: &MagickWand) -> Result<(), &'static str> {
pub fn hald_clut_image(&self, clut_wand: &MagickWand) -> Result<()> {
let result = unsafe { bindings::MagickHaldClutImage(self.wand, clut_wand.wand) };
match result {
bindings::MagickBooleanType_MagickTrue => Ok(()),
_ => Err("failed to replace colors in the image from color lookup table"),
_ => Err(MagickError(
"failed to replace colors in the image from color lookup table",
)),
}
}
@ -287,42 +291,39 @@ impl MagickWand {
MagickWand::new_from_wand(wand)
}
pub fn set_size(&self, columns: size_t, rows: size_t) -> Result<(), &'static str> {
pub fn set_size(&self, columns: size_t, rows: size_t) -> Result<()> {
let result = unsafe { bindings::MagickSetSize(self.wand, columns, rows) };
match result {
bindings::MagickBooleanType_MagickTrue => Ok(()),
_ => Err("failed to set size of wand"),
_ => Err(MagickError("failed to set size of wand")),
}
}
// 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"))]
fn quantum_range(&self) -> Result<f64, &'static str> {
return Ok(bindings::QuantumRange);
#[cfg(not(feature = "disable-hdri"))]
fn quantum_range(&self) -> Result<f64> {
Ok(bindings::QuantumRange)
}
// with disable-hdri enabled we define our own quantum_range
// values lifted directly from magick-type.h
#[cfg(feature="disable-hdri")]
fn quantum_range(&self) -> Result<f64, &'static str> {
#[cfg(feature = "disable-hdri")]
fn quantum_range(&self) -> Result<f64> {
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(MagickError(
("Quantum depth must be one of 8, 16, 32 or 64"),
)),
}
}
// Level an image. Black and white points are multiplied with QuantumRange to
// decrease dependencies on the end user.
pub fn level_image(
&self,
black_point: f64,
gamma: f64,
white_point: f64,
) -> Result<(), &'static str> {
pub fn level_image(&self, black_point: f64, gamma: f64, white_point: f64) -> Result<()> {
let quantum_range = self.quantum_range()?;
let result = unsafe {
@ -335,23 +336,17 @@ impl MagickWand {
};
match result {
bindings::MagickBooleanType_MagickTrue => Ok(()),
_ => Err("failed to set size of wand"),
_ => Err(MagickError("failed to set size of wand")),
}
}
/// 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(
&self,
width: usize,
height: usize,
x: isize,
y: isize,
) -> Result<(), &'static str> {
pub fn extend_image(&self, width: usize, height: usize, x: isize, y: isize) -> Result<()> {
let result = unsafe { bindings::MagickExtentImage(self.wand, width, height, x, y) };
match result {
bindings::MagickBooleanType_MagickTrue => Ok(()),
_ => Err("failed to extend image"),
_ => Err(MagickError("failed to extend image")),
}
}
@ -359,7 +354,7 @@ impl MagickWand {
&self,
name: &str,
profile: T,
) -> Result<(), &'static str> {
) -> Result<()> {
let c_name = CString::new(name).unwrap();
let result = unsafe {
let profile = profile.into();
@ -375,75 +370,75 @@ impl MagickWand {
};
match result {
bindings::MagickBooleanType_MagickTrue => Ok(()),
_ => Err("failed to profile image"),
_ => Err(MagickError("failed to profile image")),
}
}
pub fn flip_image(&self) -> Result<(), &'static str> {
pub fn flip_image(&self) -> Result<()> {
let result = unsafe { bindings::MagickFlipImage(self.wand) };
match result {
bindings::MagickBooleanType_MagickTrue => Ok(()),
_ => Err("failed to flip image"),
_ => Err(MagickError("failed to flip image")),
}
}
pub fn negate_image(&self) -> Result<(), &'static str> {
pub fn negate_image(&self) -> Result<()> {
let result = unsafe {
bindings::MagickNegateImage(self.wand, bindings::MagickBooleanType_MagickTrue)
};
match result {
bindings::MagickBooleanType_MagickTrue => Ok(()),
_ => Err("failed to flip image"),
_ => Err(MagickError("failed to flip image")),
}
}
pub fn flop_image(&self) -> Result<(), &'static str> {
pub fn flop_image(&self) -> Result<()> {
let result = unsafe { bindings::MagickFlopImage(self.wand) };
match result {
bindings::MagickBooleanType_MagickTrue => Ok(()),
_ => Err("failed to flip image"),
_ => Err(MagickError("failed to flip image")),
}
}
pub fn blur_image(&self, radius: f64, sigma: f64) -> Result<(), &'static str> {
pub fn blur_image(&self, radius: f64, sigma: f64) -> Result<()> {
let result = unsafe { bindings::MagickBlurImage(self.wand, radius, sigma) };
match result {
bindings::MagickBooleanType_MagickTrue => Ok(()),
_ => Err("failed to blur image"),
_ => Err(MagickError("failed to blur image")),
}
}
pub fn gaussian_blur_image(&self, radius: f64, sigma: f64) -> Result<(), &'static str> {
pub fn gaussian_blur_image(&self, radius: f64, sigma: f64) -> Result<()> {
let result = unsafe { bindings::MagickGaussianBlurImage(self.wand, radius, sigma) };
match result {
bindings::MagickBooleanType_MagickTrue => Ok(()),
_ => Err("failed to gaussian blur image"),
_ => Err(MagickError("failed to gaussian blur image")),
}
}
/// Adaptively resize the currently selected image.
pub fn adaptive_resize_image(&self, width: usize, height: usize) -> Result<(), &'static str> {
pub fn adaptive_resize_image(&self, width: usize, height: usize) -> Result<()> {
match unsafe { bindings::MagickAdaptiveResizeImage(self.wand, width, height) } {
bindings::MagickBooleanType_MagickTrue => Ok(()),
_ => Err("failed to adaptive-resize image"),
_ => Err(MagickError("failed to adaptive-resize image")),
}
}
/// Rotate the currently selected image by the given number of degrees,
/// filling any empty space with the background color of a given PixelWand
pub fn rotate_image(&self, background: &PixelWand, degrees: f64) -> Result<(), &'static str> {
pub fn rotate_image(&self, background: &PixelWand, degrees: f64) -> Result<()> {
match unsafe { bindings::MagickRotateImage(self.wand, background.wand, degrees) } {
bindings::MagickBooleanType_MagickTrue => Ok(()),
_ => Err("failed to rotate image"),
_ => Err(MagickError("failed to rotate image")),
}
}
/// Trim the image removing the backround color from the edges.
pub fn trim_image(&self, fuzz: f64) -> Result<(), &'static str> {
pub fn trim_image(&self, fuzz: f64) -> Result<()> {
let result = unsafe { bindings::MagickTrimImage(self.wand, fuzz) };
match result {
bindings::MagickBooleanType_MagickTrue => Ok(()),
_ => Err("failed to trim image"),
_ => Err(MagickError("failed to trim image")),
}
}
@ -467,22 +462,22 @@ impl MagickWand {
}
/// Reset the Wand page canvas and position.
pub fn reset_image_page(&self, page_geometry: &str) -> Result<(), &'static str> {
pub fn reset_image_page(&self, page_geometry: &str) -> Result<()> {
let c_page_geometry = CString::new(page_geometry).unwrap();
let result = unsafe { bindings::MagickResetImagePage(self.wand, c_page_geometry.as_ptr()) };
if result == bindings::MagickBooleanType_MagickTrue {
Ok(())
} else {
Err("Resetting page geometry failed.")
Err(MagickError("Resetting page geometry failed."))
}
}
/// Retrieve the named image property value.
pub fn get_image_property(&self, name: &str) -> Result<String, &'static str> {
pub fn get_image_property(&self, name: &str) -> Result<String> {
let c_name = CString::new(name).unwrap();
let result = unsafe { bindings::MagickGetImageProperty(self.wand, c_name.as_ptr()) };
let value = if result.is_null() {
Err("missing property")
Err(MagickError("missing property"))
} else {
// convert (and copy) the C string to a Rust string
let cstr = unsafe { CStr::from_ptr(result) };
@ -495,7 +490,7 @@ impl MagickWand {
}
/// Set the named image property.
pub fn set_image_property(&self, name: &str, value: &str) -> Result<(), &'static str> {
pub fn set_image_property(&self, name: &str, value: &str) -> Result<()> {
let c_name = CString::new(name).unwrap();
let c_value = CString::new(value).unwrap();
let result = unsafe {
@ -504,7 +499,7 @@ impl MagickWand {
if result == bindings::MagickBooleanType_MagickTrue {
Ok(())
} else {
Err("Setting image property failed.")
Err(MagickError("Setting image property failed."))
}
}
@ -526,7 +521,7 @@ impl MagickWand {
/// Sets the image sampling factors.
///
/// samplingFactors: An array of floats representing the sampling factor for each color component (in RGB order).
pub fn set_sampling_factors(&self, samplingFactors: &[f64]) -> Result<(), &'static str> {
pub fn set_sampling_factors(&self, samplingFactors: &[f64]) -> Result<()> {
match unsafe {
bindings::MagickSetSamplingFactors(
self.wand,
@ -535,7 +530,7 @@ impl MagickWand {
)
} {
bindings::MagickBooleanType_MagickTrue => Ok(()),
_ => Err("SetSamplingFactors returned false"),
_ => Err(MagickError("SetSamplingFactors returned false")),
}
}
@ -564,34 +559,34 @@ impl MagickWand {
///
/// sigma: the standard deviation of the Gaussian, in pixels.
///
pub fn sharpen_image(&self, radius: f64, sigma: f64) -> Result<(), &'static str> {
pub fn sharpen_image(&self, radius: f64, sigma: f64) -> Result<()> {
match unsafe { bindings::MagickSharpenImage(self.wand, radius, sigma) } {
bindings::MagickBooleanType_MagickTrue => Ok(()),
_ => Err("SharpenImage returned false"),
_ => Err(MagickError("SharpenImage returned false")),
}
}
/// Set the background color.
pub fn set_background_color(&self, pixel_wand: &PixelWand) -> Result<(), &'static str> {
pub fn set_background_color(&self, pixel_wand: &PixelWand) -> Result<()> {
match unsafe { bindings::MagickSetBackgroundColor(self.wand, pixel_wand.wand) } {
bindings::MagickBooleanType_MagickTrue => Ok(()),
_ => Err("SetBackgroundColor returned false"),
_ => Err(MagickError("SetBackgroundColor returned false")),
}
}
/// Set the image background color.
pub fn set_image_background_color(&self, pixel_wand: &PixelWand) -> Result<(), &'static str> {
pub fn set_image_background_color(&self, pixel_wand: &PixelWand) -> Result<()> {
match unsafe { bindings::MagickSetImageBackgroundColor(self.wand, pixel_wand.wand) } {
bindings::MagickBooleanType_MagickTrue => Ok(()),
_ => Err("SetImageBackgroundColor returned false"),
_ => Err(MagickError("SetImageBackgroundColor returned false")),
}
}
/// Returns the image resolution as a pair (horizontal resolution, vertical resolution)
pub fn get_image_resolution(&self) -> Result<(f64, f64), &'static str> {
pub fn get_image_resolution(&self) -> Result<(f64, f64)> {
let mut x_resolution = 0f64;
let mut y_resolution = 0f64;
unsafe {
@ -600,50 +595,46 @@ impl MagickWand {
{
Ok((x_resolution, y_resolution))
} else {
Err("GetImageResolution returned false")
Err(MagickError("GetImageResolution returned false"))
}
}
}
/// Sets the image resolution
pub fn set_image_resolution(
&self,
x_resolution: f64,
y_resolution: f64,
) -> Result<(), &'static str> {
pub fn set_image_resolution(&self, x_resolution: f64, y_resolution: f64) -> Result<()> {
unsafe {
if bindings::MagickSetImageResolution(self.wand, x_resolution, y_resolution)
== bindings::MagickBooleanType_MagickTrue
{
Ok(())
} else {
Err("SetImageResolution returned false")
Err(MagickError("SetImageResolution returned false"))
}
}
}
/// Sets the wand resolution
pub fn set_resolution(&self, x_resolution: f64, y_resolution: f64) -> Result<(), &'static str> {
pub fn set_resolution(&self, x_resolution: f64, y_resolution: f64) -> Result<()> {
unsafe {
if bindings::MagickSetResolution(self.wand, x_resolution, y_resolution)
== bindings::MagickBooleanType_MagickTrue
{
Ok(())
} else {
Err("SetResolution returned false")
Err(MagickError("SetResolution returned false"))
}
}
}
/// Returns the image resolution as a pair (horizontal resolution, vertical resolution)
pub fn sepia_tone_image(&self, threshold: f64) -> Result<(), &'static str> {
pub fn sepia_tone_image(&self, threshold: f64) -> Result<()> {
unsafe {
if bindings::MagickSepiaToneImage(self.wand, threshold * self.quantum_range()?)
== bindings::MagickBooleanType_MagickTrue
{
Ok(())
} else {
Err("SepiaToneImage returned false")
Err(MagickError("SepiaToneImage returned false"))
}
}
}
@ -701,17 +692,11 @@ impl MagickWand {
/// Extract a region of the image. The width and height is used as the size
/// of the region. X and Y is the offset.
pub fn crop_image(
&self,
width: usize,
height: usize,
x: isize,
y: isize,
) -> Result<(), &'static str> {
pub fn crop_image(&self, width: usize, height: usize, x: isize, y: isize) -> Result<()> {
let result = unsafe { bindings::MagickCropImage(self.wand, width, height, x, y) };
match result {
bindings::MagickBooleanType_MagickTrue => Ok(()),
_ => Err("failed to crop image"),
_ => Err(MagickError("failed to crop image")),
}
}
@ -719,11 +704,11 @@ impl MagickWand {
///
/// This is incredibly fast, as it does 1-1 pixel mapping for downscales, and box filtering for
/// upscales
pub fn sample_image(&self, width: usize, height: usize) -> Result<(), &'static str> {
pub fn sample_image(&self, width: usize, height: usize) -> Result<()> {
let result = unsafe { bindings::MagickSampleImage(self.wand, width, height) };
match result {
bindings::MagickBooleanType_MagickTrue => Ok(()),
_ => Err("failed to sample image"),
_ => Err(MagickError("failed to sample image")),
}
}
@ -740,20 +725,27 @@ 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<()> {
match unsafe {
bindings::MagickLiquidRescaleImage(self.wand, width, height, delta_x, rigidity)
} {
bindings::MagickBooleanType_MagickTrue => Ok(()),
_ => Err("failed to liquid-rescale image")
_ => Err(MagickError("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<()> {
match unsafe { bindings::MagickImplodeImage(self.wand, amount, method) } {
bindings::MagickBooleanType_MagickTrue => Ok(()),
_ => Err("failed to implode image")
_ => Err(MagickError("failed to implode image")),
}
}
@ -808,12 +800,12 @@ impl MagickWand {
}
/// Write the current image to the provided path.
pub fn write_image(&self, path: &str) -> Result<(), &'static str> {
pub fn write_image(&self, path: &str) -> Result<()> {
let c_name = CString::new(path).unwrap();
let result = unsafe { bindings::MagickWriteImage(self.wand, c_name.as_ptr()) };
match result {
bindings::MagickBooleanType_MagickTrue => Ok(()),
_ => Err("failed to write image"),
_ => Err(MagickError("failed to write image")),
}
}
@ -821,7 +813,7 @@ impl MagickWand {
///
/// The `format` argument may be any ImageMagick supported image
/// format (e.g. GIF, JPEG, PNG, etc).
pub fn write_image_blob(&self, format: &str) -> Result<Vec<u8>, &'static str> {
pub fn write_image_blob(&self, format: &str) -> Result<Vec<u8>> {
let c_format = CString::new(format).unwrap();
let mut length: size_t = 0;
let blob = unsafe {
@ -842,7 +834,7 @@ impl MagickWand {
///
/// The `format` argument may be any ImageMagick supported image
/// format (e.g. GIF, JPEG, PNG, etc).
pub fn write_images_blob(&self, format: &str) -> Result<Vec<u8>, &'static str> {
pub fn write_images_blob(&self, format: &str) -> Result<Vec<u8>> {
let c_format = CString::new(format).unwrap();
let mut length: size_t = 0;
let blob = unsafe {
@ -863,14 +855,14 @@ impl MagickWand {
/// That is, the image is RGB rather than RGBA or CMYK rather than CMYKA
pub fn get_image_alpha_channel(&self) -> bool {
let res = unsafe { bindings::MagickGetImageAlphaChannel(self.wand) };
return res == bindings::MagickBooleanType_MagickTrue;
res == bindings::MagickBooleanType_MagickTrue
}
/// Renders the drawing wand on the current image
pub fn draw_image(&mut self, drawing_wand: &DrawingWand) -> Result<(), &'static str> {
pub fn draw_image(&mut self, drawing_wand: &DrawingWand) -> Result<()> {
match unsafe { bindings::MagickDrawImage(self.wand, drawing_wand.wand) } {
bindings::MagickBooleanType_MagickTrue => Ok(()),
_ => Err("unable to draw image"),
_ => Err(MagickError("unable to draw image")),
}
}
@ -886,15 +878,11 @@ impl MagickWand {
/// expression to an image. Use these operators to lighten or darken an image,
/// to increase or decrease contrast in an image, or to produce the "negative"
/// of an image.
pub fn evaluate_image(
&mut self,
op: bindings::MagickEvaluateOperator,
val: f64,
) -> Result<(), &'static str> {
pub fn evaluate_image(&mut self, op: bindings::MagickEvaluateOperator, val: f64) -> Result<()> {
let res = unsafe { bindings::MagickEvaluateImage(self.wand, op, val) };
match res {
bindings::MagickBooleanType_MagickTrue => Ok(()),
_ => Err("failed to evaluate image"),
_ => Err(MagickError("failed to evaluate image")),
}
}
@ -906,31 +894,25 @@ impl MagickWand {
width: usize,
height: usize,
compose: bindings::CompositeOperator,
) -> Result<(), &'static str> {
) -> Result<()> {
match unsafe {
bindings::MagickBorderImage(self.wand, pixel_wand.wand, width, height, compose)
} {
bindings::MagickBooleanType_MagickTrue => Ok(()),
_ => Err("border image returned false"),
_ => Err(MagickError("border image returned false")),
}
}
/// Simulate an image shadow
pub fn shadow_image(
&self,
alpha: f64,
sigma: f64,
x: isize,
y: isize,
) -> Result<(), &'static str> {
pub fn shadow_image(&self, alpha: f64, sigma: f64, x: isize, y: isize) -> Result<()> {
unsafe {
if bindings::MagickShadowImage(self.wand, alpha, sigma, x, y)
== bindings::MagickBooleanType_MagickTrue
{
Ok(())
} else {
Err("ShadowImage returned false")
Err(MagickError("ShadowImage returned false"))
}
}
}
@ -944,7 +926,7 @@ impl MagickWand {
columns: usize,
rows: usize,
pixels: &Vec<u8>,
) -> Result<(), &'static str> {
) -> Result<()> {
let pixel_map = CString::new("RGBA").unwrap();
match unsafe {
bindings::MagickImportImagePixels(
@ -959,7 +941,7 @@ impl MagickWand {
)
} {
bindings::MagickBooleanType_MagickTrue => Ok(()),
_ => Err("unable to import pixels"),
_ => Err(MagickError("unable to import pixels")),
}
}

View File

@ -13,13 +13,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
use bindings;
use std::ffi::{CStr, CString};
use std::fmt;
#[cfg(target_os = "freebsd")]
use libc::size_t;
#[cfg(not(target_os = "freebsd"))]
use size_t;
use std::ffi::{CStr, CString};
use std::fmt;
use bindings;
use result::MagickError;
use crate::result::Result;
#[derive(Default, Debug)]
pub struct HSL {
@ -41,10 +46,10 @@ wand_common!(
);
impl PixelWand {
pub fn is_similar(&self, other: &PixelWand, fuzz: f64) -> Result<(), &'static str> {
pub fn is_similar(&self, other: &PixelWand, fuzz: f64) -> Result<()> {
match unsafe { bindings::IsPixelWandSimilar(self.wand, other.wand, fuzz) } {
bindings::MagickBooleanType_MagickTrue => Ok(()),
_ => Err("not similar"),
_ => Err(MagickError("not similar")),
}
}
@ -78,11 +83,11 @@ impl PixelWand {
writeln!(f, "{}}}", prefix)
}
pub fn set_color(&mut self, s: &str) -> Result<(), &'static str> {
pub fn set_color(&mut self, s: &str) -> Result<()> {
let c_string = CString::new(s).map_err(|_| "could not convert to cstring")?;
match unsafe { bindings::PixelSetColor(self.wand, c_string.as_ptr()) } {
bindings::MagickBooleanType_MagickTrue => Ok(()),
_ => Err("failed to set color"),
_ => Err(MagickError("failed to set color")),
}
}