diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ecb9bf..0f1e97f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## [0.3.0] - 2016-01-02 +### Changed +- Add `get_image_property()` function to retrieve, for example, EXIF data. + ## [0.2.3] - 2015-12-26 ### Changed - Upgrade to libc 0.2.4 in hopes of fixing downstream build incompatibilities. diff --git a/Cargo.toml b/Cargo.toml index 71748de..e6a522e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "magick_rust" -version = "0.2.3" +version = "0.3.0" authors = ["Nathan Fiedler "] description = "Selection of Rust bindings for the ImageMagick library." homepage = "https://github.com/nlfiedler/magick-rust" diff --git a/README.md b/README.md index 6f1c966..b860a26 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,6 @@ # magick-rust -A "safe" Rust interface to the [ImageMagick](http://www.imagemagick.org/) system, in particular, the MagickWand library. The word *safe* is in scarequotes because, honestly, nearly everything is little more than a call into a C function with `unsafe` wrapped around it. - -## TODO - -1. ~~Use rust-bindgen to generate Rust bindings.~~ -1. ~~Add a license and copyright headers~~ -1. Develop Rustic wrappers to the MagickWand library. - * Old Rust bindings: https://github.com/influenza/wand-of-rust - * Wand API: http://www.imagemagick.org/script/magick-wand.php -1. ~~Write unit tests~~ -1. Test it on lots of images in batches to stress test it; should not crash +A somewhat safe Rust interface to the [ImageMagick](http://www.imagemagick.org/) system, in particular, the MagickWand library. Many of the functions in the MagickWand API are still missing, and those that are needed will be gradually added. ## Build and Test diff --git a/src/lib.rs b/src/lib.rs index 85256fa..44de0a1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -31,7 +31,7 @@ extern crate libc; -use std::ffi::CString; +use std::ffi::{CStr, CString}; use std::ptr; use libc::{c_uint, c_double, c_void}; use filters::FilterType; @@ -98,6 +98,27 @@ impl MagickWand { } } + /// Retrieve the named image property value. + pub fn get_image_property(&self, name: &str) -> Result<&str, &'static str> { + 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") + } else { + let cstr = unsafe { CStr::from_ptr(result) }; + match cstr.to_str() { + Ok(v) => Ok(v), + Err(_) => Err("invalid value") + } + }; + unsafe { + bindings::MagickRelinquishMemory(result as *mut c_void); + } + value + } + /// Resize the image to the specified width and height, using the /// specified filter type with the specified blur / sharpness factor. /// diff --git a/tests/lib.rs b/tests/lib.rs index 87aa4af..c9849e4 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -111,3 +111,20 @@ fn test_fit() { assert_eq!(240, wand.get_image_width()); assert_eq!(180, wand.get_image_height()); } + +#[test] +fn test_get_image_property() { + START.call_once(|| { + magick_wand_genesis(); + }); + let wand = MagickWand::new(); + assert!(wand.read_image("tests/data/IMG_5745.JPG").is_ok()); + // retrieve a property we know exists + let found_value = wand.get_image_property("exif:DateTime"); + assert!(found_value.is_ok()); + assert_eq!("2014:04:23 13:33:08", found_value.unwrap()); + // retrieve a property that does not exist + let missing_value = wand.get_image_property("exif:Foobar"); + assert!(missing_value.is_err()); + assert_eq!("missing property", missing_value.unwrap_err()); +}