diff --git a/Cargo.toml b/Cargo.toml index e437064..ed02b12 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,5 +14,5 @@ build = "build.rs" libc = ">=0.2" [build-dependencies] -bindgen = "0.31" +bindgen = "0.52.0" pkg-config = ">=0.3" diff --git a/build.rs b/build.rs index 1e28793..76ca580 100644 --- a/build.rs +++ b/build.rs @@ -87,6 +87,37 @@ fn main() { let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); let bindings_path_str = out_dir.join("bindings.rs"); + #[derive(Debug)] + struct IgnoreMacros(HashSet); + + impl bindgen::callbacks::ParseCallbacks for IgnoreMacros { + fn will_parse_macro(&self, name: &str) -> bindgen::callbacks::MacroParsingBehavior { + if self.0.contains(name) { + bindgen::callbacks::MacroParsingBehavior::Ignore + } else { + bindgen::callbacks::MacroParsingBehavior::Default + } + } + } + + let ignored_macros = IgnoreMacros( + vec![ + "FP_INFINITE".into(), + "FP_NAN".into(), + "FP_NORMAL".into(), + "FP_SUBNORMAL".into(), + "FP_ZERO".into(), + "IPPORT_RESERVED".into(), + "FP_INT_UPWARD".into(), + "FP_INT_DOWNWARD".into(), + "FP_INT_TOWARDZERO".into(), + "FP_INT_TONEARESTFROMZERO".into(), + "FP_INT_TONEAREST".into(), + ] + .into_iter() + .collect(), + ); + if !Path::new(&bindings_path_str).exists() { // Create the header file that rust-bindgen needs as input. let gen_h_path = out_dir.join("gen.h"); @@ -101,17 +132,9 @@ fn main() { .ctypes_prefix("libc") .raw_line("extern crate libc;") .header(gen_h_path.to_str().unwrap()) - // https://github.com/rust-lang-nursery/rust-bindgen/issues/687 - .blacklist_type("FP_NAN") - .blacklist_type("FP_INFINITE") - .blacklist_type("FP_ZERO") - .blacklist_type("FP_SUBNORMAL") - .blacklist_type("FP_NORMAL") - .blacklist_type("FP_INT_UPWARD") - .blacklist_type("FP_INT_DOWNWARD") - .blacklist_type("FP_INT_TOWARDZERO") - .blacklist_type("FP_INT_TONEARESTFROMZERO") - .blacklist_type("FP_INT_TONEAREST"); + .parse_callbacks(Box::new(ignored_macros)) + .blacklist_type("timex") + .blacklist_function("clock_adjtime"); for d in include_dirs { builder = builder.clang_arg(format!("-I{}", d.to_string_lossy())); diff --git a/src/lib.rs b/src/lib.rs index 67bce28..218028c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -69,8 +69,7 @@ pub fn magick_wand_terminus() { 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 c_string = ::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() { diff --git a/src/wand/drawing.rs b/src/wand/drawing.rs index c4ccc91..3c35a92 100644 --- a/src/wand/drawing.rs +++ b/src/wand/drawing.rs @@ -35,7 +35,7 @@ wand_common!( impl DrawingWand { pub fn draw_annotation(&mut self, x: f64, y: f64, text: &str) -> Result<(), &'static str> { - let c_string = try!(CString::new(text).map_err(|_| "could not convert to cstring")); + 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(()) } @@ -94,13 +94,13 @@ impl DrawingWand { impl fmt::Debug for DrawingWand { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(writeln!(f, "DrawingWand {{")); - try!(writeln!(f, " Exception: {:?}", self.get_exception())); - try!(writeln!(f, " IsWand: {:?}", self.is_wand())); - try!(self.fmt_unchecked_settings(f, " ")); - try!(self.fmt_string_settings(f, " ")); - try!(self.fmt_string_unchecked_settings(f, " ")); - try!(self.fmt_pixel_settings(f, " ")); + writeln!(f, "DrawingWand {{")?; + writeln!(f, " Exception: {:?}", self.get_exception())?; + writeln!(f, " IsWand: {:?}", self.is_wand())?; + self.fmt_unchecked_settings(f, " ")?; + self.fmt_string_settings(f, " ")?; + self.fmt_string_unchecked_settings(f, " ")?; + self.fmt_pixel_settings(f, " ")?; writeln!(f, "}}") } } diff --git a/src/wand/macros.rs b/src/wand/macros.rs index abbdcfe..f3660bc 100644 --- a/src/wand/macros.rs +++ b/src/wand/macros.rs @@ -118,7 +118,7 @@ macro_rules! set_get { } )* pub fn fmt_checked_settings(&self, f: &mut ::std::fmt::Formatter, prefix: &str) -> ::std::fmt::Result { - $( try!(writeln!(f, "{}{:<50}: {:?}", prefix, stringify!($c_get), self.$get())); )* + $( writeln!(f, "{}{:<50}: {:?}", prefix, stringify!($c_get), self.$get())?; )* Ok(()) } } @@ -135,7 +135,7 @@ macro_rules! set_get_unchecked { } )* pub fn fmt_unchecked_settings(&self, f: &mut ::std::fmt::Formatter, prefix: &str) -> ::std::fmt::Result { - $( try!(writeln!(f, "{}{:<50}: {:?}", prefix, stringify!($c_get), self.$get())); )* + $( writeln!(f, "{}{:<50}: {:?}", prefix, stringify!($c_get), self.$get()); )* Ok(()) } } @@ -154,7 +154,7 @@ macro_rules! string_get { Ok(result) } } - } + }; } macro_rules! string_set_get { @@ -162,7 +162,7 @@ macro_rules! string_set_get { $( string_get!($get, $c_get); pub fn $set(&mut self, s: &str) -> Result<(), &'static str> { - let c_string = try!(::std::ffi::CString::new(s).map_err(|_| "could not convert to cstring")); + 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")) @@ -170,7 +170,7 @@ macro_rules! string_set_get { } )* pub fn fmt_string_settings(&self, f: &mut ::std::fmt::Formatter, prefix: &str) -> ::std::fmt::Result { - $( try!(writeln!(f, "{}{:<50}: {:?}", prefix, stringify!($c_get), self.$get())); )* + $( writeln!(f, "{}{:<50}: {:?}", prefix, stringify!($c_get), self.$get())?; )* Ok(()) } } @@ -181,13 +181,13 @@ macro_rules! string_set_get_unchecked { $( string_get!($get, $c_get); pub fn $set(&mut self, s: &str) -> Result<(), &'static str> { - let c_string = try!(::std::ffi::CString::new(s).map_err(|_| "could not convert to cstring")); + 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(()) } )* pub fn fmt_string_unchecked_settings(&self, f: &mut ::std::fmt::Formatter, prefix: &str) -> ::std::fmt::Result { - $( try!(writeln!(f, "{}{:<50}: {:?}", prefix, stringify!($c_get), self.$get())); )* + $( writeln!(f, "{}{:<50}: {:?}", prefix, stringify!($c_get), self.$get())?; )* Ok(()) } } @@ -207,8 +207,8 @@ macro_rules! pixel_set_get { )* pub fn fmt_pixel_settings(&self, f: &mut ::std::fmt::Formatter, prefix: &str) -> ::std::fmt::Result { $( - try!(writeln!(f, "{}{:<50}: ", prefix, stringify!($c_get))); - try!(self.$get().fmt_w_prefix(f, &format!("{}{:<53}", prefix, " ") )); + writeln!(f, "{}{:<50}: ", prefix, stringify!($c_get))?; + self.$get().fmt_w_prefix(f, &format!("{}{:<53}", prefix, " ") )?; )* Ok(()) } @@ -235,14 +235,14 @@ macro_rules! color_set_get { } )* pub fn fmt_color_settings(&self, f: &mut ::std::fmt::Formatter, prefix: &str) -> ::std::fmt::Result { - try!(writeln!(f, "{}Color: {:?}, normalized: {:?}\n{}hsl: {:?}", + writeln!(f, "{}Color: {:?}, normalized: {:?}\n{}hsl: {:?}", prefix, self.get_color_as_string(), self.get_color_as_normalized_string(), prefix, self.get_hsl() - )); - $( try!(writeln!(f, "{}{:<10}: {:>} quantum: {}", prefix, stringify!($c_get).split_at(8).1, self.$get(), self.$get_quantum())); )* + )?; + $( writeln!(f, "{}{:<10}: {:>} quantum: {}", prefix, stringify!($c_get).split_at(8).1, self.$get(), self.$get_quantum())?; )* Ok(()) } } diff --git a/src/wand/magick.rs b/src/wand/magick.rs index 6f48704..65dc164 100644 --- a/src/wand/magick.rs +++ b/src/wand/magick.rs @@ -75,7 +75,7 @@ impl MagickWand { angle: f64, text: &str, ) -> Result<(), &'static str> { - let c_string = try!(CString::new(text).map_err(|_| "could not convert to cstring")); + let c_string = CString::new(text).map_err(|_| "could not convert to cstring")?; match unsafe { bindings::MagickAnnotateImage( self.wand, @@ -335,6 +335,16 @@ impl MagickWand { } } + pub fn negate_image(&self) -> Result<(), &'static str> { + let result = unsafe { + bindings::MagickNegateImage(self.wand, bindings::MagickBooleanType_MagickTrue) + }; + match result { + bindings::MagickBooleanType_MagickTrue => Ok(()), + _ => Err("failed to flip image"), + } + } + pub fn flop_image(&self) -> Result<(), &'static str> { let result = unsafe { bindings::MagickFlopImage(self.wand) }; match result { @@ -831,11 +841,11 @@ impl MagickWand { impl fmt::Debug for MagickWand { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(writeln!(f, "MagickWand {{")); - try!(writeln!(f, " Exception: {:?}", self.get_exception())); - try!(writeln!(f, " IsWand: {:?}", self.is_wand())); - try!(self.fmt_string_settings(f, " ")); - try!(self.fmt_checked_settings(f, " ")); + writeln!(f, "MagickWand {{")?; + writeln!(f, " Exception: {:?}", self.get_exception())?; + writeln!(f, " IsWand: {:?}", self.is_wand())?; + self.fmt_string_settings(f, " ")?; + self.fmt_checked_settings(f, " ")?; writeln!(f, "}}") } } diff --git a/src/wand/pixel.rs b/src/wand/pixel.rs index 1cf6cdc..8d727d4 100644 --- a/src/wand/pixel.rs +++ b/src/wand/pixel.rs @@ -70,16 +70,16 @@ impl PixelWand { pub fn fmt_w_prefix(&self, f: &mut fmt::Formatter, prefix: &str) -> fmt::Result { let mut prf = prefix.to_string(); prf.push_str(" "); - try!(writeln!(f, "{}PixelWand {{", prefix)); - try!(writeln!(f, "{}Exception: {:?}", prf, self.get_exception())); - try!(writeln!(f, "{}IsWand: {:?}", prf, self.is_wand())); - try!(self.fmt_unchecked_settings(f, &prf)); - try!(self.fmt_color_settings(f, &prf)); + writeln!(f, "{}PixelWand {{", prefix)?; + writeln!(f, "{}Exception: {:?}", prf, self.get_exception())?; + writeln!(f, "{}IsWand: {:?}", prf, self.is_wand())?; + self.fmt_unchecked_settings(f, &prf)?; + self.fmt_color_settings(f, &prf)?; writeln!(f, "{}}}", prefix) } 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")); + 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"), diff --git a/tests/lib.rs b/tests/lib.rs index 91482ee..afa4e80 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -346,3 +346,18 @@ fn test_clut_image() { ) .is_ok()); } + +#[test] +fn test_negate_image() { + START.call_once(|| { + magick_wand_genesis(); + }); + let wand = MagickWand::new(); + assert!(wand.read_image("tests/data/rust.png").is_ok()); + wand.negate_image().unwrap(); + let pixel_color = wand.get_image_pixel_color(0, 0).unwrap(); + assert_eq!( + "srgb(255,255,255)", + pixel_color.get_color_as_string().unwrap() + ); +}