From bd34f145a230c46b62578aafbd1f76c771021639 Mon Sep 17 00:00:00 2001 From: Nathan Fiedler Date: Sat, 6 Oct 2018 15:37:17 -0700 Subject: [PATCH] Ran `cargo fmt` on the code base, looks better cargo test passes --- build.rs | 66 +++++---- src/conversions.rs | 5 +- src/lib.rs | 21 +-- src/wand/drawing.rs | 23 ++- src/wand/macros.rs | 23 +-- src/wand/magick.rs | 331 ++++++++++++++++++++++++++------------------ src/wand/mod.rs | 9 +- src/wand/pixel.rs | 54 +++++--- tests/lib.rs | 59 +++++--- 9 files changed, 363 insertions(+), 228 deletions(-) diff --git a/build.rs b/build.rs index fa90b57..5798819 100644 --- a/build.rs +++ b/build.rs @@ -32,7 +32,10 @@ fn main() { if cfg!(target_os = "freebsd") { // pkg_config does not seem to work properly on FreeBSD, so // hard-code the builder settings for the time being. - env_var_set_default("IMAGE_MAGICK_INCLUDE_DIRS", "/usr/local/include/ImageMagick-7"); + env_var_set_default( + "IMAGE_MAGICK_INCLUDE_DIRS", + "/usr/local/include/ImageMagick-7", + ); // Need to hack the linker flags as well. env_var_set_default("IMAGE_MAGICK_LIB_DIRS", "/usr/local/lib"); env_var_set_default("IMAGE_MAGICK_LIBS", "MagickWand-7"); @@ -41,14 +44,20 @@ fn main() { let lib_dirs = find_image_magick_lib_dirs(); for d in &lib_dirs { if !d.exists() { - panic!("ImageMagick library directory does not exist: {}", d.to_string_lossy()); + panic!( + "ImageMagick library directory does not exist: {}", + d.to_string_lossy() + ); } - println!( "cargo:rustc-link-search=native={}", d.to_string_lossy()); + println!("cargo:rustc-link-search=native={}", d.to_string_lossy()); } let include_dirs = find_image_magick_include_dirs(); for d in &include_dirs { if !d.exists() { - panic!("ImageMagick include directory does not exist: {}", d.to_string_lossy()); + panic!( + "ImageMagick include directory does not exist: {}", + d.to_string_lossy() + ); } println!("cargo:include={}", d.to_string_lossy()); } @@ -82,7 +91,9 @@ fn main() { // Create the header file that rust-bindgen needs as input. let gen_h_path = out_dir.join("gen.h"); let mut gen_h = File::create(&gen_h_path).expect("could not create file"); - gen_h.write_all(HEADER.as_bytes()).expect("could not write header file"); + gen_h + .write_all(HEADER.as_bytes()) + .expect("could not write header file"); // Geneate the bindings. let mut builder = bindgen::Builder::default() @@ -130,9 +141,7 @@ fn find_image_magick_lib_dirs() -> Vec { env::var("IMAGE_MAGICK_LIB_DIRS") .map(|x| x.split(":").map(PathBuf::from).collect::>()) .or_else(|_| Ok(vec![find_image_magick_dir()?.join("lib")])) - .or_else(|_: env::VarError| -> Result<_, env::VarError> { - Ok(run_pkg_config().link_paths) - }) + .or_else(|_: env::VarError| -> Result<_, env::VarError> { Ok(run_pkg_config().link_paths) }) .expect("Couldn't find ImageMagick library directory") } @@ -142,15 +151,13 @@ fn find_image_magick_include_dirs() -> Vec { .map(|x| x.split(":").map(PathBuf::from).collect::>()) .or_else(|_| Ok(vec![find_image_magick_dir()?.join("include")])) .or_else(|_: env::VarError| -> Result<_, env::VarError> { - Ok(run_pkg_config().include_paths) - }) - .expect("Couldn't find ImageMagick include directory") + Ok(run_pkg_config().include_paths) + }).expect("Couldn't find ImageMagick include directory") } fn find_image_magick_dir() -> Result { println!("cargo:rerun-if-env-changed=IMAGE_MAGICK_DIR"); - env::var("IMAGE_MAGICK_DIR") - .map(PathBuf::from) + env::var("IMAGE_MAGICK_DIR").map(PathBuf::from) } fn determine_mode>(libdirs: &Vec, libs: &[T]) -> &'static str { @@ -164,19 +171,21 @@ fn determine_mode>(libdirs: &Vec, libs: &[T]) -> &'static // See what files we actually have to link against, and see what our // possibilities even are. - let files = libdirs.into_iter().flat_map(|d| d.read_dir().unwrap()) + let files = libdirs + .into_iter() + .flat_map(|d| d.read_dir().unwrap()) .map(|e| e.unwrap()) .map(|e| e.file_name()) .filter_map(|e| e.into_string().ok()) .collect::>(); let can_static = libs.iter().all(|l| { - files.contains(&format!("lib{}.a", l.as_ref())) || - files.contains(&format!("{}.lib", l.as_ref())) + files.contains(&format!("lib{}.a", l.as_ref())) + || files.contains(&format!("{}.lib", l.as_ref())) }); let can_dylib = libs.iter().all(|l| { - files.contains(&format!("lib{}.so", l.as_ref())) || - files.contains(&format!("{}.dll", l.as_ref())) || - files.contains(&format!("lib{}.dylib", l.as_ref())) + files.contains(&format!("lib{}.so", l.as_ref())) + || files.contains(&format!("{}.dll", l.as_ref())) + || files.contains(&format!("lib{}.dylib", l.as_ref())) }); match (can_static, can_dylib) { @@ -185,7 +194,7 @@ fn determine_mode>(libdirs: &Vec, libs: &[T]) -> &'static (false, false) => { panic!( "ImageMagick libdirs at `{:?}` do not contain the required files \ - to either statically or dynamically link ImageMagick", + to either statically or dynamically link ImageMagick", libdirs ); } @@ -209,14 +218,21 @@ fn run_pkg_config() -> pkg_config::Library { // pkg-config crate always adds those other flags, we must run the // command directly. if !Command::new("pkg-config") - .arg(format!("--max-version={}", MAX_VERSION)) - .arg("MagickWand") - .status().unwrap().success() { - panic!(format!("MagickWand version must be no higher than {}", MAX_VERSION)); + .arg(format!("--max-version={}", MAX_VERSION)) + .arg("MagickWand") + .status() + .unwrap() + .success() + { + panic!(format!( + "MagickWand version must be no higher than {}", + MAX_VERSION + )); } // 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). pkg_config::Config::new() .cargo_metadata(false) - .probe("MagickWand").unwrap() + .probe("MagickWand") + .unwrap() } diff --git a/src/conversions.rs b/src/conversions.rs index 351e513..e888e9f 100644 --- a/src/conversions.rs +++ b/src/conversions.rs @@ -33,7 +33,10 @@ pub trait ToMagick { fn to_magick(self) -> T; } -impl ToMagick for E where T: FromRust { +impl ToMagick for E +where + T: FromRust, +{ fn to_magick(self) -> T { >::from_rust(self) } diff --git a/src/lib.rs b/src/lib.rs index 714d24e..2b74c60 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -28,17 +28,19 @@ #![allow(non_upper_case_globals)] #![allow(non_camel_case_types)] #![allow(non_snake_case)] -#![allow(improper_ctypes)] // the siginfo_t in waitid() definition in bindings.rs +#![allow(improper_ctypes)] // the siginfo_t in waitid() definition in bindings.rs extern crate libc; -mod wand; mod conversions; +mod wand; include!(concat!(env!("OUT_DIR"), "/bindings.rs")); -pub use wand::*; -pub use bindings::{MetricType, FilterType, ColorspaceType, DitherMethod, CompositeOperator, GravityType}; +pub use bindings::{ + ColorspaceType, CompositeOperator, DitherMethod, FilterType, GravityType, MetricType, +}; pub use conversions::ToMagick; +pub use wand::*; use libc::size_t; #[cfg(not(target_os = "freebsd"))] @@ -50,7 +52,7 @@ pub fn magick_wand_genesis() { unsafe { match bindings::IsMagickWandInstantiated() { bindings::MagickBooleanType_MagickTrue => (), - _ => bindings::MagickWandGenesis() + _ => bindings::MagickWandGenesis(), } } } @@ -61,15 +63,17 @@ pub fn magick_wand_terminus() { unsafe { match bindings::IsMagickWandInstantiated() { bindings::MagickBooleanType_MagickTrue => bindings::MagickWandTerminus(), - _ => () + _ => (), } } } pub fn magick_query_fonts(pattern: &str) -> Result, &'static str> { let mut number_fonts: size_t = 0; - let c_string = try!(::std::ffi::CString::new(pattern).map_err(|_| "could not convert to cstring")); - let ptr = unsafe { bindings::MagickQueryFonts(c_string.as_ptr(), &mut number_fonts as *mut size_t) }; + let c_string = + try!(::std::ffi::CString::new(pattern).map_err(|_| "could not convert to cstring")); + let ptr = + unsafe { bindings::MagickQueryFonts(c_string.as_ptr(), &mut number_fonts as *mut size_t) }; if ptr.is_null() { Err("null ptr returned by magick_query_fonts") } else { @@ -81,5 +85,4 @@ pub fn magick_query_fonts(pattern: &str) -> Result, &'static str> { } Ok(v) } - } diff --git a/src/wand/drawing.rs b/src/wand/drawing.rs index dc75b24..c4ccc91 100644 --- a/src/wand/drawing.rs +++ b/src/wand/drawing.rs @@ -13,18 +13,24 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -use std::fmt; -use std::ffi::{CStr, CString}; -use ::bindings; +use bindings; #[cfg(target_os = "freebsd")] use libc::size_t; #[cfg(not(target_os = "freebsd"))] -use ::size_t; +use size_t; +use std::ffi::{CStr, CString}; +use std::fmt; wand_common!( DrawingWand, - NewDrawingWand, ClearDrawingWand, IsDrawingWand, CloneDrawingWand, DestroyDrawingWand, - DrawClearException, DrawGetExceptionType, DrawGetException + NewDrawingWand, + ClearDrawingWand, + IsDrawingWand, + CloneDrawingWand, + DestroyDrawingWand, + DrawClearException, + DrawGetExceptionType, + DrawGetException ); impl DrawingWand { @@ -42,7 +48,10 @@ impl DrawingWand { ); string_set_get_unchecked!( - get_text_encoding, set_text_encoding, DrawGetTextEncoding, DrawSetTextEncoding + get_text_encoding, + set_text_encoding, + DrawGetTextEncoding, + DrawSetTextEncoding ); pixel_set_get!( diff --git a/src/wand/macros.rs b/src/wand/macros.rs index 1750068..10db8d0 100644 --- a/src/wand/macros.rs +++ b/src/wand/macros.rs @@ -19,13 +19,13 @@ macro_rules! wand_common { $clear_exc:ident, $get_exc_type:ident, $get_exc:ident ) => { pub struct $wand { - pub wand: *mut ::bindings::$wand + pub wand: *mut ::bindings::$wand, } impl $wand { pub fn new() -> Self { $wand { - wand: unsafe { ::bindings::$new_wand() } + wand: unsafe { ::bindings::$new_wand() }, } } @@ -36,7 +36,7 @@ macro_rules! wand_common { fn clear_exception(&mut self) -> Result<(), &'static str> { match unsafe { ::bindings::$clear_exc(self.wand) } { ::bindings::MagickBooleanType_MagickTrue => Ok(()), - _ => Err(concat!("failed to clear", stringify!($wand), "exception")) + _ => Err(concat!("failed to clear", stringify!($wand), "exception")), } } @@ -45,11 +45,16 @@ macro_rules! wand_common { } fn get_exception(&self) -> Result<(String, ::bindings::ExceptionType), &'static str> { - let mut severity: ::bindings::ExceptionType = ::bindings::ExceptionType_UndefinedException; + 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!("null ptr returned by", stringify!($wand), "get_exception")) + Err(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)) @@ -59,7 +64,7 @@ macro_rules! wand_common { pub fn is_wand(&self) -> Result<(), &'static str> { match unsafe { ::bindings::$is_wand(self.wand) } { ::bindings::MagickBooleanType_MagickTrue => Ok(()), - _ => Err(concat!(stringify!($wand), " not a wand")) + _ => Err(concat!(stringify!($wand), " not a wand")), } } } @@ -67,7 +72,7 @@ macro_rules! wand_common { impl Clone for $wand { fn clone(&self) -> Self { $wand { - wand: unsafe { ::bindings::$clone(self.wand) } + wand: unsafe { ::bindings::$clone(self.wand) }, } } } @@ -80,7 +85,7 @@ macro_rules! wand_common { } } } - } + }; } macro_rules! get { @@ -165,7 +170,6 @@ macro_rules! string_set_get { } } - macro_rules! string_set_get_unchecked { ($($get:ident, $set:ident, $c_get:ident, $c_set:ident )*) => { $( @@ -183,7 +187,6 @@ macro_rules! string_set_get_unchecked { } } - macro_rules! pixel_set_get { ($($get:ident, $set:ident, $c_get:ident, $c_set:ident )*) => { $( diff --git a/src/wand/magick.rs b/src/wand/magick.rs index 27502ad..175c21b 100644 --- a/src/wand/magick.rs +++ b/src/wand/magick.rs @@ -13,22 +13,28 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -use std::{fmt, ptr, slice}; +use libc::c_void; use std::ffi::{CStr, CString}; -use libc::{c_void}; +use std::{fmt, ptr, slice}; +use super::{DrawingWand, PixelWand}; +use bindings; +use conversions::*; #[cfg(target_os = "freebsd")] use libc::{size_t, ssize_t}; #[cfg(not(target_os = "freebsd"))] -use ::{size_t, ssize_t}; -use ::bindings; -use ::conversions::*; -use super::{DrawingWand, PixelWand}; +use {size_t, ssize_t}; wand_common!( MagickWand, - NewMagickWand, ClearMagickWand, IsMagickWand, CloneMagickWand, DestroyMagickWand, - MagickClearException, MagickGetExceptionType, MagickGetException + NewMagickWand, + ClearMagickWand, + IsMagickWand, + CloneMagickWand, + DestroyMagickWand, + MagickClearException, + MagickGetExceptionType, + MagickGetException ); /// MagickWand is a Rustic wrapper to the Rust bindings to ImageMagick. @@ -38,8 +44,12 @@ wand_common!( /// 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<(), &'static str> { match unsafe { bindings::MagickNewImage(self.wand, columns, rows, pixel_wand.wand) } { bindings::MagickBooleanType_MagickTrue => Ok(()), _ => Err("Could not create image"), @@ -49,20 +59,35 @@ impl MagickWand { 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(); - let result = unsafe { - bindings::MagickSetOption(self.wand, c_key.as_ptr(), c_value.as_ptr()) - }; + 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"), } } - pub fn annotate_image(&mut self, drawing_wand: &DrawingWand, x: f64, y: f64, angle: f64, text: &str) -> Result<(), &'static str> { + pub fn annotate_image( + &mut self, + drawing_wand: &DrawingWand, + x: f64, + y: f64, + angle: f64, + text: &str, + ) -> Result<(), &'static str> { let c_string = try!(CString::new(text).map_err(|_| "could not convert to cstring")); - match unsafe { bindings::MagickAnnotateImage(self.wand, drawing_wand.wand, x, y, angle, c_string.as_ptr() as *const _) } { + match unsafe { + bindings::MagickAnnotateImage( + self.wand, + drawing_wand.wand, + x, + y, + angle, + c_string.as_ptr() as *const _, + ) + } { bindings::MagickBooleanType_MagickTrue => Ok(()), - _ => Err("unable to annotate image") + _ => Err("unable to annotate image"), } } @@ -70,48 +95,43 @@ impl MagickWand { pub fn add_image(&mut self, other_wand: &MagickWand) -> Result<(), &'static str> { match unsafe { bindings::MagickAddImage(self.wand, other_wand.wand) } { bindings::MagickBooleanType_MagickTrue => Ok(()), - _ => Err("unable to add images from another wand") + _ => Err("unable to add images from another wand"), } } pub fn append_all(&mut self, stack: bool) -> MagickWand { unsafe { bindings::MagickResetIterator(self.wand) }; MagickWand { - wand: unsafe { bindings::MagickAppendImages(self.wand, stack.to_magick()) } + wand: unsafe { bindings::MagickAppendImages(self.wand, stack.to_magick()) }, } } pub fn label_image(&self, label: &str) -> Result<(), &'static str> { let c_label = CString::new(label).unwrap(); - let result = unsafe { - bindings::MagickLabelImage(self.wand, c_label.as_ptr()) - }; + let result = unsafe { bindings::MagickLabelImage(self.wand, c_label.as_ptr()) }; match result { bindings::MagickBooleanType_MagickTrue => Ok(()), - _ => Err("failed to add label") + _ => Err("failed to add label"), } } pub fn write_images(&self, path: &str, adjoin: bool) -> Result<(), &'static str> { let c_name = CString::new(path).unwrap(); - let result = unsafe { - bindings::MagickWriteImages(self.wand, c_name.as_ptr(), adjoin.to_magick()) - }; + 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("failed to write images"), } } /// Read the image data from the named file. pub fn read_image(&self, path: &str) -> Result<(), &'static str> { let c_name = CString::new(path).unwrap(); - let result = unsafe { - bindings::MagickReadImage(self.wand, c_name.as_ptr()) - }; + let result = unsafe { bindings::MagickReadImage(self.wand, c_name.as_ptr()) }; match result { bindings::MagickBooleanType_MagickTrue => Ok(()), - _ => Err("failed to read image") + _ => Err("failed to read image"), } } @@ -121,11 +141,14 @@ impl MagickWand { let size = int_slice.len(); let result = unsafe { bindings::MagickReadImageBlob( - self.wand, int_slice.as_ptr() as *const c_void, size as size_t) + self.wand, + int_slice.as_ptr() as *const c_void, + size as size_t, + ) }; match result { bindings::MagickBooleanType_MagickTrue => Ok(()), - _ => Err("failed to read image") + _ => Err("failed to read image"), } } @@ -133,12 +156,10 @@ impl MagickWand { /// without reading data. pub fn ping_image(&self, path: &str) -> Result<(), &'static str> { let c_name = CString::new(path).unwrap(); - let result = unsafe { - bindings::MagickPingImage(self.wand, c_name.as_ptr()) - }; + let result = unsafe { bindings::MagickPingImage(self.wand, c_name.as_ptr()) }; match result { bindings::MagickBooleanType_MagickTrue => Ok(()), - _ => Err("failed to ping image") + _ => Err("failed to ping image"), } } @@ -149,105 +170,127 @@ impl MagickWand { let size = int_slice.len(); let result = unsafe { bindings::MagickPingImageBlob( - self.wand, int_slice.as_ptr() as *const c_void, size as size_t) + self.wand, + int_slice.as_ptr() as *const c_void, + size as size_t, + ) }; match result { bindings::MagickBooleanType_MagickTrue => Ok(()), - _ => Err("failed to ping image") + _ => Err("failed to ping image"), } } /// Compare two images and return tuple `(distortion, diffImage)` /// `diffImage` is `None` if `distortion == 0` - pub fn compare_images(&self, reference: &MagickWand, metric: bindings::MetricType) -> (f64, Option) { + pub fn compare_images( + &self, + reference: &MagickWand, + metric: bindings::MetricType, + ) -> (f64, Option) { let mut distortion: f64 = 0.0; let result = unsafe { bindings::MagickCompareImages(self.wand, reference.wand, metric, &mut distortion) }; let wand = if result.is_null() { None - } - else { + } else { Some(MagickWand { wand: result }) }; (distortion, wand) } /// Compose another image onto self at (x, y) using composition_operator - pub fn compose_images(&self, reference: &MagickWand, composition_operator: bindings::CompositeOperator, clip_to_self: bool, x: isize, y: isize) -> Result<(), &'static str> { + pub fn compose_images( + &self, + reference: &MagickWand, + composition_operator: bindings::CompositeOperator, + clip_to_self: bool, + x: isize, + y: isize, + ) -> Result<(), &'static str> { let native_clip_to_self = if clip_to_self { bindings::MagickBooleanType_MagickTrue } else { bindings::MagickBooleanType_MagickFalse }; let result = unsafe { - bindings::MagickCompositeImage(self.wand, reference.wand, - composition_operator, native_clip_to_self, x, y + bindings::MagickCompositeImage( + self.wand, + reference.wand, + composition_operator, + native_clip_to_self, + x, + y, ) }; match result { bindings::MagickBooleanType_MagickTrue => Ok(()), - _ => Err("failed to compose images") + _ => Err("failed to compose images"), } } /// 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> { - let result = unsafe { - bindings::MagickExtentImage(self.wand, width, height, x, y) - }; + pub fn extend_image( + &self, + width: usize, + height: usize, + x: isize, + y: isize, + ) -> Result<(), &'static str> { + let result = unsafe { bindings::MagickExtentImage(self.wand, width, height, x, y) }; match result { bindings::MagickBooleanType_MagickTrue => Ok(()), - _ => Err("failed to extend image") + _ => Err("failed to extend image"), } } - pub fn profile_image<'a, T: Into>>(&self, name: &str, profile: T) -> Result<(), &'static str> { + pub fn profile_image<'a, T: Into>>( + &self, + name: &str, + profile: T, + ) -> Result<(), &'static str> { let c_name = CString::new(name).unwrap(); let result = unsafe { let profile = profile.into(); let profile_ptr = match profile { Some(data) => data.as_ptr(), - None => ptr::null() + None => ptr::null(), } as *const c_void; let profile_len = match profile { Some(data) => data.len(), - None => 0 + None => 0, }; bindings::MagickProfileImage(self.wand, c_name.as_ptr(), profile_ptr, profile_len) }; match result { bindings::MagickBooleanType_MagickTrue => Ok(()), - _ => Err("failed to profile image") + _ => Err("failed to profile image"), } } pub fn flip_image(&self) -> Result<(), &'static str> { - let result = unsafe { - bindings::MagickFlipImage(self.wand) - }; + let result = unsafe { bindings::MagickFlipImage(self.wand) }; match result { bindings::MagickBooleanType_MagickTrue => Ok(()), - _ => Err("failed to flip image") + _ => Err("failed to flip image"), } } pub fn flop_image(&self) -> Result<(), &'static str> { - let result = unsafe { - bindings::MagickFlopImage(self.wand) - }; + let result = unsafe { bindings::MagickFlopImage(self.wand) }; match result { bindings::MagickBooleanType_MagickTrue => Ok(()), - _ => Err("failed to flip image") + _ => Err("failed to flip image"), } } /// Adaptively resize the currently selected image. pub fn adaptive_resize_image(&self, width: usize, height: usize) -> Result<(), &'static str> { - match unsafe { bindings::MagickAdaptiveResizeImage(self.wand, width, height)} { + match unsafe { bindings::MagickAdaptiveResizeImage(self.wand, width, height) } { bindings::MagickBooleanType_MagickTrue => Ok(()), - _ => Err("failed to adaptive-resize image") + _ => Err("failed to adaptive-resize image"), } } @@ -256,33 +299,27 @@ impl MagickWand { pub fn rotate_image(&self, background: &PixelWand, degrees: f64) -> Result<(), &'static str> { match unsafe { bindings::MagickRotateImage(self.wand, background.wand, degrees) } { bindings::MagickBooleanType_MagickTrue => Ok(()), - _ => Err("failed to rotate image") + _ => Err("failed to rotate image"), } } /// Trim the image removing the backround color from the edges. pub fn trim_image(&self, fuzz: f64) -> Result<(), &'static str> { - let result = unsafe { - bindings::MagickTrimImage(self.wand, fuzz) - }; + let result = unsafe { bindings::MagickTrimImage(self.wand, fuzz) }; match result { bindings::MagickBooleanType_MagickTrue => Ok(()), - _ => Err("failed to trim image") + _ => Err("failed to trim image"), } } /// Retrieve the width of the image. pub fn get_image_width(&self) -> usize { - unsafe { - bindings::MagickGetImageWidth(self.wand) as usize - } + unsafe { bindings::MagickGetImageWidth(self.wand) as usize } } /// Retrieve the height of the image. pub fn get_image_height(&self) -> usize { - unsafe { - bindings::MagickGetImageHeight(self.wand) as usize - } + unsafe { bindings::MagickGetImageHeight(self.wand) as usize } } /// Retrieve the page geometry (width, height, x offset, y offset) of the image. @@ -297,9 +334,7 @@ impl MagickWand { /// Reset the Wand page canvas and position. pub fn reset_image_page(&self, page_geometry: &str) -> Result<(), &'static str> { let c_page_geometry = CString::new(page_geometry).unwrap(); - let result = unsafe { - bindings::MagickResetImagePage(self.wand, c_page_geometry.as_ptr()) - }; + let result = unsafe { bindings::MagickResetImagePage(self.wand, c_page_geometry.as_ptr()) }; if result == bindings::MagickBooleanType_MagickTrue { Ok(()) } else { @@ -310,9 +345,7 @@ impl MagickWand { /// Retrieve the named image property value. pub fn get_image_property(&self, name: &str) -> Result { let c_name = CString::new(name).unwrap(); - let result = unsafe { - bindings::MagickGetImageProperty(self.wand, c_name.as_ptr()) - }; + let result = unsafe { bindings::MagickGetImageProperty(self.wand, c_name.as_ptr()) }; let value = if result.is_null() { Err("missing property") } else { @@ -345,7 +378,9 @@ impl MagickWand { let pw = PixelWand::new(); unsafe { - if bindings::MagickGetImagePixelColor(self.wand, x, y, pw.wand) == bindings::MagickBooleanType_MagickTrue { + if bindings::MagickGetImagePixelColor(self.wand, x, y, pw.wand) + == bindings::MagickBooleanType_MagickTrue + { Some(pw) } else { None @@ -357,9 +392,15 @@ impl MagickWand { /// /// 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> { - match unsafe { bindings::MagickSetSamplingFactors(self.wand, samplingFactors.len(), &samplingFactors[0]) } { + match unsafe { + bindings::MagickSetSamplingFactors( + self.wand, + samplingFactors.len(), + &samplingFactors[0], + ) + } { bindings::MagickBooleanType_MagickTrue => Ok(()), - _ => Err("SetSamplingFactors returned false") + _ => Err("SetSamplingFactors returned false"), } } @@ -370,9 +411,12 @@ impl MagickWand { unsafe { bindings::MagickGetImageHistogram(self.wand, &mut color_count) .as_mut() - .map(|ptrs| slice::from_raw_parts(ptrs, color_count) - .iter().map(|raw_wand| PixelWand { wand: *raw_wand }) - .collect()) + .map(|ptrs| { + slice::from_raw_parts(ptrs, color_count) + .iter() + .map(|raw_wand| PixelWand { wand: *raw_wand }) + .collect() + }) } } @@ -387,25 +431,19 @@ impl MagickWand { /// pub fn sharpen_image(&self, radius: f64, sigma: f64) -> Result<(), &'static str> { match unsafe { bindings::MagickSharpenImage(self.wand, radius, sigma) } { - bindings::MagickBooleanType_MagickTrue => Ok(()), - - _ => Err("SharpenImage returned false") - + + _ => Err("SharpenImage returned false"), } } /// Set the image background color. pub fn set_image_background_color(&self, pixel_wand: &PixelWand) -> Result<(), &'static str> { - match unsafe { bindings::MagickSetImageBackgroundColor(self.wand, pixel_wand.wand) } { - bindings::MagickBooleanType_MagickTrue => Ok(()), - - _ => Err("SetImageBackgroundColor returned false") - + + _ => Err("SetImageBackgroundColor returned false"), } - } /// Returns the image resolution as a pair (horizontal resolution, vertical resolution) @@ -413,7 +451,9 @@ impl MagickWand { let mut x_resolution = 0f64; let mut y_resolution = 0f64; unsafe { - if bindings::MagickGetImageResolution(self.wand, &mut x_resolution, &mut y_resolution) == bindings::MagickBooleanType_MagickTrue { + if bindings::MagickGetImageResolution(self.wand, &mut x_resolution, &mut y_resolution) + == bindings::MagickBooleanType_MagickTrue + { Ok((x_resolution, y_resolution)) } else { Err("GetImageResolution returned false") @@ -422,9 +462,15 @@ impl MagickWand { } /// 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<(), &'static str> { unsafe { - if bindings::MagickSetImageResolution(self.wand, x_resolution, y_resolution) == bindings::MagickBooleanType_MagickTrue { + if bindings::MagickSetImageResolution(self.wand, x_resolution, y_resolution) + == bindings::MagickBooleanType_MagickTrue + { Ok(()) } else { Err("SetImageResolution returned false") @@ -435,7 +481,9 @@ impl MagickWand { /// Sets the wand resolution pub fn set_resolution(&self, x_resolution: f64, y_resolution: f64) -> Result<(), &'static str> { unsafe { - if bindings::MagickSetResolution(self.wand, x_resolution, y_resolution) == bindings::MagickBooleanType_MagickTrue { + if bindings::MagickSetResolution(self.wand, x_resolution, y_resolution) + == bindings::MagickBooleanType_MagickTrue + { Ok(()) } else { Err("SetResolution returned false") @@ -446,7 +494,9 @@ impl MagickWand { /// Returns the image resolution as a pair (horizontal resolution, vertical resolution) pub fn sepia_tone_image(&self, threshold: f64) -> Result<(), &'static str> { unsafe { - if bindings::MagickSepiaToneImage(self.wand, threshold * bindings::QuantumRange) == bindings::MagickBooleanType_MagickTrue { + if bindings::MagickSepiaToneImage(self.wand, threshold * bindings::QuantumRange) + == bindings::MagickBooleanType_MagickTrue + { Ok(()) } else { Err("SepiaToneImage returned false") @@ -456,15 +506,31 @@ impl MagickWand { /// Extracts pixel data from the image as a vector of 0..255 values defined by `map`. /// See https://www.imagemagick.org/api/magick-image.php#MagickExportImagePixels for more information. - pub fn export_image_pixels(&self, x: isize, y: isize, width: usize, height: usize, map: &str) -> Option> { + pub fn export_image_pixels( + &self, + x: isize, + y: isize, + width: usize, + height: usize, + map: &str, + ) -> Option> { let c_map = CString::new(map).unwrap(); let capacity = width * height * map.len(); let mut pixels = Vec::with_capacity(capacity); unsafe { pixels.set_len(capacity as usize); - if bindings::MagickExportImagePixels(self.wand, x, y, width, height, c_map.as_ptr(), - bindings::StorageType_CharPixel, pixels.as_mut_ptr() as *mut c_void) == bindings::MagickBooleanType_MagickTrue { + if bindings::MagickExportImagePixels( + self.wand, + x, + y, + width, + height, + c_map.as_ptr(), + bindings::StorageType_CharPixel, + pixels.as_mut_ptr() as *mut c_void, + ) == bindings::MagickBooleanType_MagickTrue + { Some(pixels) } else { None @@ -474,35 +540,38 @@ impl MagickWand { /// Resize the image to the specified width and height, using the /// specified filter type. - pub fn resize_image(&self, width: usize, height: usize, - filter: bindings::FilterType) { + pub fn resize_image(&self, width: usize, height: usize, filter: bindings::FilterType) { unsafe { - bindings::MagickResizeImage( - self.wand, width as size_t, height as size_t, filter - ); + bindings::MagickResizeImage(self.wand, width as size_t, height as size_t, filter); } } /// 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> { - let result = unsafe { - bindings::MagickCropImage(self.wand, width, height, x, y) - }; + pub fn crop_image( + &self, + width: usize, + height: usize, + x: isize, + y: isize, + ) -> Result<(), &'static str> { + let result = unsafe { bindings::MagickCropImage(self.wand, width, height, x, y) }; match result { bindings::MagickBooleanType_MagickTrue => Ok(()), - _ => Err("failed to crop image") + _ => Err("failed to crop image"), } } /// Resample the image to the specified horizontal and vertical resolution, using the /// specified filter type. - pub fn resample_image(&self, x_resolution: f64, y_resolution: f64, - filter: bindings::FilterType) { + pub fn resample_image( + &self, + x_resolution: f64, + y_resolution: f64, + filter: bindings::FilterType, + ) { unsafe { - bindings::MagickResampleImage( - self.wand, x_resolution, y_resolution, filter - ); + bindings::MagickResampleImage(self.wand, x_resolution, y_resolution, filter); } } @@ -525,8 +594,12 @@ impl MagickWand { unsafe { bindings::MagickResetIterator(self.wand); while bindings::MagickNextImage(self.wand) != bindings::MagickBooleanType_MagickFalse { - bindings::MagickResizeImage(self.wand, new_width, new_height, - bindings::FilterType_LanczosFilter); + bindings::MagickResizeImage( + self.wand, + new_width, + new_height, + bindings::FilterType_LanczosFilter, + ); } } } @@ -535,7 +608,8 @@ impl MagickWand { /// hence should be "auto" oriented so it is suitable for viewing. pub fn requires_orientation(&self) -> bool { unsafe { - bindings::MagickGetImageOrientation(self.wand) != bindings::OrientationType_TopLeftOrientation + bindings::MagickGetImageOrientation(self.wand) + != bindings::OrientationType_TopLeftOrientation } } @@ -552,12 +626,10 @@ impl MagickWand { /// Write the current image to the provided path. pub fn write_image(&self, path: &str) -> Result<(), &'static str> { let c_name = CString::new(path).unwrap(); - let result = unsafe { - bindings::MagickWriteImage(self.wand, c_name.as_ptr()) - }; + let result = unsafe { bindings::MagickWriteImage(self.wand, c_name.as_ptr()) }; match result { bindings::MagickBooleanType_MagickTrue => Ok(()), - _ => Err("failed to write image") + _ => Err("failed to write image"), } } @@ -627,9 +699,7 @@ impl MagickWand { MagickUniqueImageColors => unique_image_colors() ); - get!( - get_image_colors, MagickGetImageColors, size_t - ); + get!(get_image_colors, MagickGetImageColors, size_t); string_set_get!( get_filename, set_filename, MagickGetFilename, MagickSetFilename @@ -670,7 +740,6 @@ impl MagickWand { get_pointsize, set_pointsize, MagickGetPointsize, MagickSetPointsize, f64 get_type, set_type, MagickGetType, MagickSetType, bindings::ImageType ); - } impl fmt::Debug for MagickWand { diff --git a/src/wand/mod.rs b/src/wand/mod.rs index 211f2a9..29601df 100644 --- a/src/wand/mod.rs +++ b/src/wand/mod.rs @@ -13,11 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#[macro_use] mod macros; -mod magick; +#[macro_use] +mod macros; mod drawing; +mod magick; mod pixel; -pub use self::magick::MagickWand; pub use self::drawing::DrawingWand; -pub use self::pixel::{HSL, PixelWand}; +pub use self::magick::MagickWand; +pub use self::pixel::{PixelWand, HSL}; diff --git a/src/wand/pixel.rs b/src/wand/pixel.rs index 70e95e8..1cf6cdc 100644 --- a/src/wand/pixel.rs +++ b/src/wand/pixel.rs @@ -13,53 +13,58 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -use std::fmt; -use std::ffi::{CStr, CString}; -use ::bindings; +use bindings; #[cfg(target_os = "freebsd")] use libc::size_t; #[cfg(not(target_os = "freebsd"))] -use ::size_t; +use size_t; +use std::ffi::{CStr, CString}; +use std::fmt; #[derive(Default, Debug)] pub struct HSL { pub hue: f64, pub saturation: f64, - pub lightness: f64 + pub lightness: f64, } wand_common!( PixelWand, - NewPixelWand, ClearPixelWand, IsPixelWand, ClonePixelWand, DestroyPixelWand, - PixelClearException, PixelGetExceptionType, PixelGetException + NewPixelWand, + ClearPixelWand, + IsPixelWand, + ClonePixelWand, + DestroyPixelWand, + PixelClearException, + PixelGetExceptionType, + PixelGetException ); impl PixelWand { pub fn is_similar(&self, other: &PixelWand, fuzz: f64) -> Result<(), &'static str> { match unsafe { bindings::IsPixelWandSimilar(self.wand, other.wand, fuzz) } { bindings::MagickBooleanType_MagickTrue => Ok(()), - _ => Err("not similar") + _ => Err("not similar"), } } pub fn get_hsl(&self) -> HSL { let mut hsl = HSL::default(); - unsafe { bindings::PixelGetHSL( - self.wand, - &mut hsl.hue as *mut _, - &mut hsl.saturation as *mut _, - &mut hsl.lightness as *mut _ - );} + unsafe { + bindings::PixelGetHSL( + self.wand, + &mut hsl.hue as *mut _, + &mut hsl.saturation as *mut _, + &mut hsl.lightness as *mut _, + ); + } hsl } pub fn set_hsl(&self, hsl: &HSL) { - unsafe { bindings::PixelSetHSL( - self.wand, - hsl.hue, - hsl.saturation, - hsl.lightness - );} + unsafe { + bindings::PixelSetHSL(self.wand, hsl.hue, hsl.saturation, hsl.lightness); + } } pub fn fmt_w_prefix(&self, f: &mut fmt::Formatter, prefix: &str) -> fmt::Result { @@ -75,14 +80,17 @@ impl PixelWand { pub fn set_color(&mut self, s: &str) -> Result<(), &'static str> { let c_string = try!(CString::new(s).map_err(|_| "could not convert to cstring")); - match unsafe { bindings::PixelSetColor(self.wand, c_string.as_ptr())} { + match unsafe { bindings::PixelSetColor(self.wand, c_string.as_ptr()) } { bindings::MagickBooleanType_MagickTrue => Ok(()), - _ => Err("failed to set color") + _ => Err("failed to set color"), } } string_get!(get_color_as_string, PixelGetColorAsString); - string_get!(get_color_as_normalized_string, PixelGetColorAsNormalizedString); + string_get!( + get_color_as_normalized_string, + PixelGetColorAsNormalizedString + ); set_get_unchecked!( get_color_count, set_color_count, PixelGetColorCount, PixelSetColorCount, size_t diff --git a/tests/lib.rs b/tests/lib.rs index 3cef02f..9d9fccb 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -16,14 +16,14 @@ extern crate magick_rust; -use magick_rust::{MagickWand, magick_wand_genesis, PixelWand, bindings}; +use magick_rust::{bindings, magick_wand_genesis, MagickWand, PixelWand}; +use magick_rust::ToMagick; use std::error::Error; use std::fs::File; use std::io::Read; use std::path::Path; use std::sync::{Once, ONCE_INIT}; -use magick_rust::ToMagick; // Used to make sure MagickWand is initialized exactly once. Note that we // do not bother shutting down, we simply exit when the tests are done. @@ -48,11 +48,11 @@ fn test_resize_image() { assert_eq!(384, wand.get_image_height()); let halfwidth = match wand.get_image_width() { 1 => 1, - width => width / 2 + width => width / 2, }; let halfheight = match wand.get_image_height() { 1 => 1, - height => height / 2 + height => height / 2, }; wand.resize_image(halfwidth, halfheight, bindings::FilterType_LanczosFilter); assert_eq!(256, wand.get_image_width()); @@ -69,12 +69,12 @@ fn test_read_from_blob() { let path = Path::new("tests/data/IMG_5745.JPG"); let mut file = match File::open(&path) { Err(why) => panic!("couldn't open file: {}", Error::description(&why)), - Ok(file) => file + Ok(file) => file, }; let mut data: Vec = Vec::new(); match file.read_to_end(&mut data) { Err(why) => panic!("couldn't read file: {}", Error::description(&why)), - Ok(_) => () + Ok(_) => (), }; assert!(wand.read_image_blob(&data).is_ok()); assert_eq!(512, wand.get_image_width()); @@ -186,7 +186,8 @@ fn test_compare_images() { assert!(wand2.read_image("tests/data/IMG_5745_rotl.JPG").is_ok()); wand2.auto_orient(); - let (distortion, diff) = wand1.compare_images(&wand2, bindings::MetricType_RootMeanSquaredErrorMetric); + let (distortion, diff) = + wand1.compare_images(&wand2, bindings::MetricType_RootMeanSquaredErrorMetric); assert!(distortion < 0.01); assert!(diff.is_some()); } @@ -225,21 +226,32 @@ fn test_transform_image_colorspace() { }); let wand = MagickWand::new(); assert!(wand.read_image("tests/data/IMG_5745.JPG").is_ok()); - assert_eq!(wand.get_image_colorspace(), bindings::ColorspaceType_sRGBColorspace); + assert_eq!( + wand.get_image_colorspace(), + bindings::ColorspaceType_sRGBColorspace + ); let pixel_color = wand.get_image_pixel_color(10, 10).unwrap(); assert_ne!(pixel_color.get_hsl().hue, 0.0); - assert!(wand.transform_image_colorspace(bindings::ColorspaceType_GRAYColorspace).is_ok()); - assert_eq!(wand.get_image_colorspace(), bindings::ColorspaceType_GRAYColorspace); + assert!( + wand.transform_image_colorspace(bindings::ColorspaceType_GRAYColorspace) + .is_ok() + ); + assert_eq!( + wand.get_image_colorspace(), + bindings::ColorspaceType_GRAYColorspace + ); let pixel_grayscale = wand.get_image_pixel_color(10, 10).unwrap(); assert_eq!(pixel_grayscale.get_hsl().hue, 0.0); /* The output of `export_image_pixels` should match * `convert -type Grayscale tests/data/IMG_5745.JPG[2x2+0+0] txt:` */ - assert_eq!(wand.export_image_pixels(0, 0, 2, 2, "I").unwrap(), - vec![212, 212, 210, 210]) + assert_eq!( + wand.export_image_pixels(0, 0, 2, 2, "I").unwrap(), + vec![212, 212, 210, 210] + ) } #[test] @@ -254,17 +266,27 @@ fn test_color_reduction() { let image_colors = wand.get_image_colors(); assert!(image_colors > 38000 || image_colors < 40000); - assert!(wand.quantize_image(6, bindings::ColorspaceType_RGBColorspace, 1, - bindings::DitherMethod_UndefinedDitherMethod, false.to_magick()).is_ok()); + assert!( + wand.quantize_image( + 6, + bindings::ColorspaceType_RGBColorspace, + 1, + bindings::DitherMethod_UndefinedDitherMethod, + false.to_magick() + ).is_ok() + ); assert_eq!(6, wand.get_image_colors()); let histogram = wand.get_image_histogram().unwrap(); assert_eq!(6, histogram.len()); - assert_eq!(wand.get_image_width() * wand.get_image_height(), - histogram.iter().fold(0, |total_colors, wand| total_colors + wand.get_color_count())); + assert_eq!( + wand.get_image_width() * wand.get_image_height(), + histogram.iter().fold(0, |total_colors, wand| total_colors + + wand.get_color_count()) + ); } -#[test] +#[test] fn test_set_image_background_color() { START.call_once(|| { magick_wand_genesis(); @@ -274,7 +296,8 @@ fn test_set_image_background_color() { let mut pw = PixelWand::new(); pw.set_color("#0000FF").unwrap(); wand.set_image_background_color(&pw).unwrap(); - wand.set_image_alpha_channel(bindings::AlphaChannelOption_RemoveAlphaChannel).unwrap(); + wand.set_image_alpha_channel(bindings::AlphaChannelOption_RemoveAlphaChannel) + .unwrap(); let blob = wand.write_image_blob("rgb").unwrap(); assert_eq!(0u8, blob[0]); assert_eq!(0u8, blob[1]);