From dc8453dc6727cb99f6c5c05a7791bb6e30331409 Mon Sep 17 00:00:00 2001 From: Drew Short Date: Sun, 6 Mar 2016 18:12:23 -0600 Subject: [PATCH] Ran rustfmt --- src/cache.rs | 99 +++++--- src/hash/ahash.rs | 6 +- src/hash/dhash.rs | 6 +- src/hash/mod.rs | 17 +- src/hash/phash.rs | 19 +- src/lib.rs | 621 +++++++++++++++++++++++++--------------------- src/main.rs | 11 +- 7 files changed, 433 insertions(+), 346 deletions(-) diff --git a/src/cache.rs b/src/cache.rs index 52f71e9..2356713 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -34,7 +34,9 @@ struct CacheMetadata { } impl Default for CacheMetadata { - fn default() -> CacheMetadata { CacheMetadata { cache_version: CACHE_VERSION } } + fn default() -> CacheMetadata { + CacheMetadata { cache_version: CACHE_VERSION } + } } impl PartialEq for CacheMetadata { @@ -56,7 +58,12 @@ pub struct Cache<'a> { } impl<'a> Default for Cache<'a> { - fn default() -> Cache<'a> { Cache {cache_dir: CACHE_DIR, use_cache: true } } + fn default() -> Cache<'a> { + Cache { + cache_dir: CACHE_DIR, + use_cache: true, + } + } } impl<'a> Cache<'a> { @@ -75,40 +82,42 @@ impl<'a> Cache<'a> { let mut loaded_metadata_string = String::new(); match file.read_to_string(&mut loaded_metadata_string) { Ok(_) => { - let loaded_metadata: CacheMetadata = match json::decode(&loaded_metadata_string) { - Ok(data) => data, - Err(_) => CacheMetadata { cache_version: 0 }, - }; + let loaded_metadata: CacheMetadata = + match json::decode(&loaded_metadata_string) { + Ok(data) => data, + Err(_) => CacheMetadata { cache_version: 0 }, + }; // If they match, continue if current_metadata != loaded_metadata { // If they don't wipe the cache to start new match remove_dir_all(self.cache_dir) { - Ok(_) => { + Ok(_) => { match create_dir_all(self.cache_dir) { Ok(_) => (), Err(e) => println!("Error: {}", e), } - }, + } Err(e) => println!("Error: {}", e), }; }; - }, + } Err(e) => println!("Error: {}", e), }; - }, - // Metadata file doesn't exist, do nothing assume all is well, create new metadata file - Err(_) => {}, + } + // Metadata file doesn't exist, do nothing assume all is well, + // create new metadata file + Err(_) => {} }; let encoded_cache_metadata = json::encode(¤t_metadata).unwrap(); match File::create(&metadata_path) { Ok(mut file) => { let _ = file.write(&encoded_cache_metadata.as_bytes()); Ok(()) - }, - Err(e) => Err(e) + } + Err(e) => Err(e), } - }, + } Err(e) => Err(e), } } @@ -136,11 +145,11 @@ impl<'a> Cache<'a> { /** * Put an image buffer in the cache */ - pub fn put_image_in_cache(&self, - path: &Path, - size: u32, - image: &ImageBuffer, Vec>) - -> Result { + pub fn put_image_in_cache(&self, + path: &Path, + size: u32, + image: &ImageBuffer, Vec>) + -> Result { let hash = self.get_file_hash(&path); match hash { Ok(sha1) => { @@ -162,7 +171,7 @@ impl<'a> Cache<'a> { return Err(e); } } - }, + } Err(e) => println!("Error: {}", e), } } @@ -209,21 +218,28 @@ impl<'a> Cache<'a> { None } } - } else { None } + } else { + None + } } /** * Expects a slice of slices that represents lines in the file */ pub fn put_matrix_in_cache(&self, - path: &Path, - size: u32, - file_contents: &Vec>) - -> Result { + path: &Path, + size: u32, + file_contents: &Vec>) + -> Result { let hash = self.get_file_hash(&path); match hash { Ok(sha1) => { - let cache_path_str = format!("{}/matrix/{}x{}/{}.{}", self.cache_dir, size, size, sha1, CACHED_MATRIX_EXT); + let cache_path_str = format!("{}/matrix/{}x{}/{}.{}", + self.cache_dir, + size, + size, + sha1, + CACHED_MATRIX_EXT); let cache_dir_str = format!("{}/matrix/{}x{}", self.cache_dir, size, size); match create_dir_all(cache_dir_str) { Ok(_) => { @@ -231,10 +247,14 @@ impl<'a> Cache<'a> { // Save the file into the cache match File::create(&cached_path) { Ok(mut file) => { - let mut compressor = ZlibEncoder::new(Vec::new(), Compression::Default); + let mut compressor = ZlibEncoder::new(Vec::new(), + Compression::Default); for row in file_contents { let mut row_str = row.iter().fold(String::new(), - |acc, &item| acc + &format!("{},", item)); + |acc, &item| { + acc + + &format!("{},", item) + }); // remove the last comma let desire_len = row_str.len() - 1; row_str.truncate(desire_len); @@ -255,7 +275,7 @@ impl<'a> Cache<'a> { return Err(e); } } - }, + } Err(e) => println!("Error: {}", e), } } @@ -270,16 +290,18 @@ impl<'a> Cache<'a> { /** * Get a matrix out of the cache */ - pub fn get_matrix_from_cache(&self, - path: &Path, - size: u32) - -> Option>> { + pub fn get_matrix_from_cache(&self, path: &Path, size: u32) -> Option>> { if self.use_cache { let hash = self.get_file_hash(&path); match hash { Ok(sha1) => { // Check if the file exists in the cache - let cache_path_str = format!("{}/matrix/{}x{}/{}.{}", CACHE_DIR, size, size, sha1, CACHED_MATRIX_EXT); + let cache_path_str = format!("{}/matrix/{}x{}/{}.{}", + CACHE_DIR, + size, + size, + sha1, + CACHED_MATRIX_EXT); let cached_path = Path::new(&cache_path_str); // Try to open, if it does, then we can read the image in match File::open(&cached_path) { @@ -299,7 +321,8 @@ impl<'a> Cache<'a> { .map(|line| { line.split(",") .map(|f| { - f64::from_str(f).unwrap() + f64::from_str(f) + .unwrap() }) .collect() }) @@ -317,7 +340,9 @@ impl<'a> Cache<'a> { None } } - } else { None } + } else { + None + } } } diff --git a/src/hash/ahash.rs b/src/hash/ahash.rs index 319bbc5..c41d080 100644 --- a/src/hash/ahash.rs +++ b/src/hash/ahash.rs @@ -15,7 +15,9 @@ pub struct AHash<'a> { impl<'a> AHash<'a> { pub fn new(path: &'a Path, precision: &Precision, cache: &'a Cache) -> Self { - AHash { prepared_image: Box::new(prepare_image(&path, &HashType::AHash, &precision, &cache)) } + AHash { + prepared_image: Box::new(prepare_image(&path, &HashType::AHash, &precision, &cache)), + } } } @@ -58,4 +60,4 @@ impl<'a> PerceptualHash for AHash<'a> { hash } -} \ No newline at end of file +} diff --git a/src/hash/dhash.rs b/src/hash/dhash.rs index 9781649..974aed0 100644 --- a/src/hash/dhash.rs +++ b/src/hash/dhash.rs @@ -15,7 +15,9 @@ pub struct DHash<'a> { impl<'a> DHash<'a> { pub fn new(path: &'a Path, precision: &Precision, cache: &'a Cache) -> Self { - DHash { prepared_image: Box::new(prepare_image(&path, &HashType::DHash, &precision, &cache)) } + DHash { + prepared_image: Box::new(prepare_image(&path, &HashType::DHash, &precision, &cache)), + } } } @@ -59,4 +61,4 @@ impl<'a> PerceptualHash for DHash<'a> { hash } -} \ No newline at end of file +} diff --git a/src/hash/mod.rs b/src/hash/mod.rs index a0f4c9f..4010d3b 100644 --- a/src/hash/mod.rs +++ b/src/hash/mod.rs @@ -128,7 +128,7 @@ pub fn prepare_image<'a>(path: &'a Path, PreparedImage { orig_path: &*image_path, image: image, - cache: &cache + cache: &cache, } } None => { @@ -152,18 +152,25 @@ pub fn prepare_image<'a>(path: &'a Path, /** * Get a specific HashType hash */ -pub fn get_perceptual_hash<'a>(path: &'a Path, precision: &Precision, hash_type: &HashType, cache: &Cache) -> u64 { +pub fn get_perceptual_hash<'a>(path: &'a Path, + precision: &Precision, + hash_type: &HashType, + cache: &Cache) + -> u64 { match *hash_type { HashType::AHash => ahash::AHash::new(&path, &precision, &cache).get_hash(), HashType::DHash => dhash::DHash::new(&path, &precision, &cache).get_hash(), - HashType::PHash => phash::PHash::new(&path, &precision, &cache).get_hash() + HashType::PHash => phash::PHash::new(&path, &precision, &cache).get_hash(), } } /** * Get all perceptual hashes for an image */ -pub fn get_perceptual_hashes<'a>(path: &'a Path, precision: &Precision, cache: &Cache) -> PerceptualHashes<'a> { +pub fn get_perceptual_hashes<'a>(path: &'a Path, + precision: &Precision, + cache: &Cache) + -> PerceptualHashes<'a> { let image_path = path.to_str().unwrap(); let ahash = ahash::AHash::new(&path, &precision, &cache).get_hash(); let dhash = dhash::DHash::new(&path, &precision, &cache).get_hash(); @@ -194,4 +201,4 @@ pub fn calculate_hamming_distance(hash1: u64, hash2: u64) -> u64 { } } hamming -} \ No newline at end of file +} diff --git a/src/hash/phash.rs b/src/hash/phash.rs index fc49f29..28a1409 100644 --- a/src/hash/phash.rs +++ b/src/hash/phash.rs @@ -17,7 +17,9 @@ pub struct PHash<'a> { impl<'a> PHash<'a> { pub fn new(path: &'a Path, precision: &Precision, cache: &'a Cache) -> Self { - PHash { prepared_image: Box::new(prepare_image(&path, &HashType::PHash, &precision, &cache)) } + PHash { + prepared_image: Box::new(prepare_image(&path, &HashType::PHash, &precision, &cache)), + } } } @@ -39,8 +41,9 @@ impl<'a> PerceptualHash for PHash<'a> { // Pretty fast already, so caching doesn't make a huge difference // Atleast compared to opening and processing the images let mut data_matrix: Vec> = Vec::new(); - match self.prepared_image.cache.get_matrix_from_cache(&Path::new(self.prepared_image.orig_path), - width as u32) { + match self.prepared_image + .cache + .get_matrix_from_cache(&Path::new(self.prepared_image.orig_path), width as u32) { Some(matrix) => data_matrix = matrix, None => { // Preparing the results @@ -60,9 +63,11 @@ impl<'a> PerceptualHash for PHash<'a> { // Perform the 2D DFT operation on our matrix calculate_2d_dft(&mut data_matrix); // Store this DFT in the cache - match self.prepared_image.cache.put_matrix_in_cache(&Path::new(self.prepared_image.orig_path), - width as u32, - &data_matrix) { + match self.prepared_image + .cache + .put_matrix_in_cache(&Path::new(self.prepared_image.orig_path), + width as u32, + &data_matrix) { Ok(_) => {} Err(e) => println!("Unable to store matrix in cache. {}", e), }; @@ -216,4 +221,4 @@ fn test_2d_dft() { assert!(test_matrix[3][1] == 2_f64); assert!(test_matrix[3][2] == -2_f64); assert!(test_matrix[3][3] == 0_f64); -} \ No newline at end of file +} diff --git a/src/lib.rs b/src/lib.rs index be06155..29df06d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,304 +13,351 @@ use std::path::Path; use std::ffi::CStr; use cache::Cache; -static LIB_CACHE: Cache<'static> = Cache { cache_dir: cache::CACHE_DIR, use_cache: true }; +static LIB_CACHE: Cache<'static> = Cache { + cache_dir: cache::CACHE_DIR, + use_cache: true, +}; /** * Prepare the library for work. * * Not performing this step may cause parts to fail. */ - #[no_mangle] - pub extern "C" fn init() { - match LIB_CACHE.init() { - Ok(_) => {} - Err(e) => println!("Error: {}", e), - } - } +#[no_mangle] +pub extern "C" fn init() { + match LIB_CACHE.init() { + Ok(_) => {} + Err(e) => println!("Error: {}", e), + } +} /** * Teardown for the library */ - #[no_mangle] - pub extern "C" fn teardown() { - match LIB_CACHE.clean() { - Ok(_) => {} - Err(e) => println!("Error: {}", e), - } - } - - pub fn get_phashes(path: &Path) -> hash::PerceptualHashes { - hash::get_perceptual_hashes(path, &hash::Precision::Medium, &LIB_CACHE) - } - - - pub fn get_ahash(path: &Path) -> u64 { - hash::get_perceptual_hash(&path, &hash::Precision::Medium, &hash::HashType::AHash, &LIB_CACHE) - } - - pub fn get_dhash(path: &Path) -> u64 { - hash::get_perceptual_hash(&path, &hash::Precision::Medium, &hash::HashType::DHash, &LIB_CACHE) - } - - pub fn get_phash(path: &Path) -> u64 { - hash::get_perceptual_hash(&path, &hash::Precision::Medium, &hash::HashType::DHash, &LIB_CACHE) - } - - pub fn get_hamming_distance(hash1: u64, hash2: u64) -> u64 { - hash::calculate_hamming_distance(hash1, hash2) - } - - // External proxies for the get_*hash methods - - #[no_mangle] - pub extern "C" fn ext_get_ahash(path_char: *const libc::c_char) -> libc::uint64_t { - unsafe { - let path_str = CStr::from_ptr(path_char); - let image_path = match path_str.to_str() { - Ok(result) => result, - Err(e) => { - println!("Error: {}. Unable to parse '{}'", - e, - to_hex_string(path_str.to_bytes())); - panic!("Unable to parse path") - } - }; - let path = Path::new(&image_path); - get_ahash(&path) - } - } - - #[no_mangle] - pub extern "C" fn ext_get_dhash(path_char: *const libc::c_char) -> libc::uint64_t { - unsafe { - let path_str = CStr::from_ptr(path_char); - let image_path = match path_str.to_str() { - Ok(result) => result, - Err(e) => { - println!("Error: {}. Unable to parse '{}'", - e, - to_hex_string(path_str.to_bytes())); - panic!("Unable to parse path") - } - }; - let path = Path::new(&image_path); - get_dhash(&path) - } - } - - #[no_mangle] - pub extern "C" fn ext_get_phash(path_char: *const libc::c_char) -> libc::uint64_t { - unsafe { - let path_str = CStr::from_ptr(path_char); - let image_path = match path_str.to_str() { - Ok(result) => result, - Err(e) => { - println!("Error: {}. Unable to parse '{}'", - e, - to_hex_string(path_str.to_bytes())); - panic!("Unable to parse path") - } - }; - let path = Path::new(&image_path); - get_phash(&path) - } - } - - fn to_hex_string(bytes: &[u8]) -> String { - println!("length: {}", bytes.len()); - let mut strs: Vec = Vec::new(); - for byte in bytes { - // println!("{:02x}", byte); - strs.push(format!("{:02x}", byte)); - } - strs.join("\\x") - } - - // Module for the tests - // +#[no_mangle] +pub extern "C" fn teardown() { + match LIB_CACHE.clean() { + Ok(_) => {} + Err(e) => println!("Error: {}", e), + } +} + +pub fn get_phashes(path: &Path) -> hash::PerceptualHashes { + hash::get_perceptual_hashes(path, &hash::Precision::Medium, &LIB_CACHE) +} + + +pub fn get_ahash(path: &Path) -> u64 { + hash::get_perceptual_hash(&path, + &hash::Precision::Medium, + &hash::HashType::AHash, + &LIB_CACHE) +} + +pub fn get_dhash(path: &Path) -> u64 { + hash::get_perceptual_hash(&path, + &hash::Precision::Medium, + &hash::HashType::DHash, + &LIB_CACHE) +} + +pub fn get_phash(path: &Path) -> u64 { + hash::get_perceptual_hash(&path, + &hash::Precision::Medium, + &hash::HashType::DHash, + &LIB_CACHE) +} + +pub fn get_hamming_distance(hash1: u64, hash2: u64) -> u64 { + hash::calculate_hamming_distance(hash1, hash2) +} + +// External proxies for the get_*hash methods + +#[no_mangle] +pub extern "C" fn ext_get_ahash(path_char: *const libc::c_char) -> libc::uint64_t { + unsafe { + let path_str = CStr::from_ptr(path_char); + let image_path = match path_str.to_str() { + Ok(result) => result, + Err(e) => { + println!("Error: {}. Unable to parse '{}'", + e, + to_hex_string(path_str.to_bytes())); + panic!("Unable to parse path") + } + }; + let path = Path::new(&image_path); + get_ahash(&path) + } +} + +#[no_mangle] +pub extern "C" fn ext_get_dhash(path_char: *const libc::c_char) -> libc::uint64_t { + unsafe { + let path_str = CStr::from_ptr(path_char); + let image_path = match path_str.to_str() { + Ok(result) => result, + Err(e) => { + println!("Error: {}. Unable to parse '{}'", + e, + to_hex_string(path_str.to_bytes())); + panic!("Unable to parse path") + } + }; + let path = Path::new(&image_path); + get_dhash(&path) + } +} + +#[no_mangle] +pub extern "C" fn ext_get_phash(path_char: *const libc::c_char) -> libc::uint64_t { + unsafe { + let path_str = CStr::from_ptr(path_char); + let image_path = match path_str.to_str() { + Ok(result) => result, + Err(e) => { + println!("Error: {}. Unable to parse '{}'", + e, + to_hex_string(path_str.to_bytes())); + panic!("Unable to parse path") + } + }; + let path = Path::new(&image_path); + get_phash(&path) + } +} + +fn to_hex_string(bytes: &[u8]) -> String { + println!("length: {}", bytes.len()); + let mut strs: Vec = Vec::new(); + for byte in bytes { + // println!("{:02x}", byte); + strs.push(format!("{:02x}", byte)); + } + strs.join("\\x") +} + +// Module for the tests +// #[cfg(test)] - mod tests { - - use std::fs; - use std::path::Path; - use hash; - - #[test] - fn test_can_get_test_images() { - let paths = fs::read_dir(&Path::new("./test_images")).unwrap(); - let mut num_paths = 0; - for path in paths { - let orig_path = path.unwrap().path(); - let ext = Path::new(&orig_path).extension(); - match ext { - Some(_) => { - if ext.unwrap() == "jpg" { - num_paths += 1; - println!("Is a image {}: {:?}", num_paths, orig_path) ; - } - } - _ => { - println!("Not an image: {:?}", orig_path) ; - continue; - } - } - // println!("Name: {}", path.unwrap().path().display()) - } - // Currently 12 images in the test imaages directory - assert!(num_paths == 12); - } - - /** +mod tests { + + use std::fs; + use std::path::Path; + use hash; + + #[test] + fn test_can_get_test_images() { + let paths = fs::read_dir(&Path::new("./test_images")).unwrap(); + let mut num_paths = 0; + for path in paths { + let orig_path = path.unwrap().path(); + let ext = Path::new(&orig_path).extension(); + match ext { + Some(_) => { + if ext.unwrap() == "jpg" { + num_paths += 1; + println!("Is a image {}: {:?}", num_paths, orig_path) ; + } + } + _ => { + println!("Not an image: {:?}", orig_path) ; + continue; + } + } + // println!("Name: {}", path.unwrap().path().display()) + } + // Currently 12 images in the test imaages directory + assert!(num_paths == 12); + } + + /** * Updated test function. Assumes 3 images to a set and no hamming distances. * We don't need to confirm that the hamming distance calculation works in these tests. */ - fn test_imageset_hash(hash_type: hash::HashType, - hash_precision: hash::Precision, - image_paths: [&Path; 3], - image_hashes: [u64; 3]) { - for index in 0..image_paths.len() { - let image_path = image_paths[index]; - let calculated_hash = hash::get_perceptual_hash(&image_path, &hash_precision, &hash_type, &super::LIB_CACHE); - println!("Image hashes for '{}': expected: {} actual: {}", - image_path.to_str().unwrap(), - image_hashes[index], - calculated_hash); - assert!(calculated_hash == image_hashes[index]); - } - } - - #[test] - fn test_confirm_ahash_results() { - // Prep_Cache - super::init(); - - // Sample_01 tests - let sample_01_images: [&Path; 3] = [&Path::new("./test_images/sample_01_large.jpg"), - &Path::new("./test_images/sample_01_medium.jpg"), - &Path::new("./test_images/sample_01_small.jpg")]; - let sample_01_hashes: [u64; 3] = [857051991849750, - 857051991849750, - 857051991849750]; - test_imageset_hash(hash::HashType::AHash, hash::Precision::Medium, sample_01_images, sample_01_hashes); - - // Sample_02 tests - let sample_02_images: [&Path; 3] = [&Path::new("./test_images/sample_02_large.jpg"), - &Path::new("./test_images/sample_02_medium.jpg"), - &Path::new("./test_images/sample_02_small.jpg")]; - let sample_02_hashes: [u64; 3] = [18446744073441116160, - 18446744073441116160, - 18446744073441116160]; - test_imageset_hash(hash::HashType::AHash, hash::Precision::Medium, sample_02_images, sample_02_hashes); - - // Sample_03 tests - let sample_03_images: [&Path; 3] = [&Path::new("./test_images/sample_03_large.jpg"), - &Path::new("./test_images/sample_03_medium.jpg"), - &Path::new("./test_images/sample_03_small.jpg")]; - let sample_03_hashes: [u64; 3] = [135670932300497406, - 135670932300497406, - 135670932300497406]; - test_imageset_hash(hash::HashType::AHash, hash::Precision::Medium, sample_03_images, sample_03_hashes); - - // Sample_04 tests - let sample_04_images: [&Path; 3] = [&Path::new("./test_images/sample_04_large.jpg"), - &Path::new("./test_images/sample_04_medium.jpg"), - &Path::new("./test_images/sample_04_small.jpg")]; - let sample_04_hashes: [u64; 3] = [18446460933225054208, - 18446460933090836480, - 18446460933090836480]; - test_imageset_hash(hash::HashType::AHash, hash::Precision::Medium, sample_04_images, sample_04_hashes); - - // Clean_Cache - // super::teardown(); - } - - #[test] - fn test_confirm_dhash_results() { - // Prep_Cache - super::init(); - - // Sample_01 tests - let sample_01_images: [&Path; 3] = [&Path::new("./test_images/sample_01_large.jpg"), - &Path::new("./test_images/sample_01_medium.jpg"), - &Path::new("./test_images/sample_01_small.jpg")]; - let sample_01_hashes: [u64; 3] = [7937395827556495926, - 7937395827556495926, - 7939647627370181174]; - test_imageset_hash(hash::HashType::DHash, hash::Precision::Medium, sample_01_images, sample_01_hashes); - - // Sample_02 tests - let sample_02_images: [&Path; 3] = [&Path::new("./test_images/sample_02_large.jpg"), - &Path::new("./test_images/sample_02_medium.jpg"), - &Path::new("./test_images/sample_02_small.jpg")]; - let sample_02_hashes: [u64; 3] = [11009829669713008949, - 11009829670249879861, - 11009829669713008949]; - test_imageset_hash(hash::HashType::DHash, hash::Precision::Medium, sample_02_images, sample_02_hashes); - - // Sample_03 tests - let sample_03_images: [&Path; 3] = [&Path::new("./test_images/sample_03_large.jpg"), - &Path::new("./test_images/sample_03_medium.jpg"), - &Path::new("./test_images/sample_03_small.jpg")]; - let sample_03_hashes: [u64; 3] = [225528496439353286, - 225528496439353286, - 226654396346195908]; - test_imageset_hash(hash::HashType::DHash, hash::Precision::Medium, sample_03_images, sample_03_hashes); - - // Sample_04 tests - let sample_04_images: [&Path; 3] = [&Path::new("./test_images/sample_04_large.jpg"), - &Path::new("./test_images/sample_04_medium.jpg"), - &Path::new("./test_images/sample_04_small.jpg")]; - let sample_04_hashes: [u64; 3] = [14620651386429567209, - 14620651386429567209, - 14620651386429567209]; - test_imageset_hash(hash::HashType::DHash, hash::Precision::Medium, sample_04_images, sample_04_hashes); - - // Clean_Cache - // super::teardown(); - } - - #[test] - fn test_confirm_phash_results() { - // Prep_Cache - super::init(); - - // Sample_01 tests - let sample_01_images: [&Path; 3] = [&Path::new("./test_images/sample_01_large.jpg"), - &Path::new("./test_images/sample_01_medium.jpg"), - &Path::new("./test_images/sample_01_small.jpg")]; - let sample_01_hashes: [u64; 3] = [72357778504597504, - 72357778504597504, - 72357778504597504]; - test_imageset_hash(hash::HashType::PHash, hash::Precision::Medium, sample_01_images, sample_01_hashes); - - // Sample_02 tests - let sample_02_images: [&Path; 3] = [&Path::new("./test_images/sample_02_large.jpg"), - &Path::new("./test_images/sample_02_medium.jpg"), - &Path::new("./test_images/sample_02_small.jpg")]; - let sample_02_hashes: [u64; 3] = [5332332327550844928, - 5332332327550844928, - 5332332327550844928]; - test_imageset_hash(hash::HashType::PHash, hash::Precision::Medium, sample_02_images, sample_02_hashes); - - // Sample_03 tests - let sample_03_images: [&Path; 3] = [&Path::new("./test_images/sample_03_large.jpg"), - &Path::new("./test_images/sample_03_medium.jpg"), - &Path::new("./test_images/sample_03_small.jpg")]; - let sample_03_hashes: [u64; 3] = [6917529027641081856, - 6917529027641081856, - 6917529027641081856]; - test_imageset_hash(hash::HashType::PHash, hash::Precision::Medium, sample_03_images, sample_03_hashes); - - // Sample_04 tests - let sample_04_images: [&Path; 3] = [&Path::new("./test_images/sample_04_large.jpg"), - &Path::new("./test_images/sample_04_medium.jpg"), - &Path::new("./test_images/sample_04_small.jpg")]; - let sample_04_hashes: [u64; 3] = [10997931646002397184, - 10997931646002397184, - 11142046834078253056]; - test_imageset_hash(hash::HashType::PHash, hash::Precision::Medium, sample_04_images, sample_04_hashes); - - // Clean_Cache - // super::teardown(); - } - } + fn test_imageset_hash(hash_type: hash::HashType, + hash_precision: hash::Precision, + image_paths: [&Path; 3], + image_hashes: [u64; 3]) { + for index in 0..image_paths.len() { + let image_path = image_paths[index]; + let calculated_hash = hash::get_perceptual_hash(&image_path, + &hash_precision, + &hash_type, + &super::LIB_CACHE); + println!("Image hashes for '{}': expected: {} actual: {}", + image_path.to_str().unwrap(), + image_hashes[index], + calculated_hash); + assert!(calculated_hash == image_hashes[index]); + } + } + + #[test] + fn test_confirm_ahash_results() { + // Prep_Cache + super::init(); + + // Sample_01 tests + let sample_01_images: [&Path; 3] = [&Path::new("./test_images/sample_01_large.jpg"), + &Path::new("./test_images/sample_01_medium.jpg"), + &Path::new("./test_images/sample_01_small.jpg")]; + let sample_01_hashes: [u64; 3] = [857051991849750, 857051991849750, 857051991849750]; + test_imageset_hash(hash::HashType::AHash, + hash::Precision::Medium, + sample_01_images, + sample_01_hashes); + + // Sample_02 tests + let sample_02_images: [&Path; 3] = [&Path::new("./test_images/sample_02_large.jpg"), + &Path::new("./test_images/sample_02_medium.jpg"), + &Path::new("./test_images/sample_02_small.jpg")]; + let sample_02_hashes: [u64; 3] = [18446744073441116160, + 18446744073441116160, + 18446744073441116160]; + test_imageset_hash(hash::HashType::AHash, + hash::Precision::Medium, + sample_02_images, + sample_02_hashes); + + // Sample_03 tests + let sample_03_images: [&Path; 3] = [&Path::new("./test_images/sample_03_large.jpg"), + &Path::new("./test_images/sample_03_medium.jpg"), + &Path::new("./test_images/sample_03_small.jpg")]; + let sample_03_hashes: [u64; 3] = [135670932300497406, + 135670932300497406, + 135670932300497406]; + test_imageset_hash(hash::HashType::AHash, + hash::Precision::Medium, + sample_03_images, + sample_03_hashes); + + // Sample_04 tests + let sample_04_images: [&Path; 3] = [&Path::new("./test_images/sample_04_large.jpg"), + &Path::new("./test_images/sample_04_medium.jpg"), + &Path::new("./test_images/sample_04_small.jpg")]; + let sample_04_hashes: [u64; 3] = [18446460933225054208, + 18446460933090836480, + 18446460933090836480]; + test_imageset_hash(hash::HashType::AHash, + hash::Precision::Medium, + sample_04_images, + sample_04_hashes); + + // Clean_Cache + // super::teardown(); + } + + #[test] + fn test_confirm_dhash_results() { + // Prep_Cache + super::init(); + + // Sample_01 tests + let sample_01_images: [&Path; 3] = [&Path::new("./test_images/sample_01_large.jpg"), + &Path::new("./test_images/sample_01_medium.jpg"), + &Path::new("./test_images/sample_01_small.jpg")]; + let sample_01_hashes: [u64; 3] = [7937395827556495926, + 7937395827556495926, + 7939647627370181174]; + test_imageset_hash(hash::HashType::DHash, + hash::Precision::Medium, + sample_01_images, + sample_01_hashes); + + // Sample_02 tests + let sample_02_images: [&Path; 3] = [&Path::new("./test_images/sample_02_large.jpg"), + &Path::new("./test_images/sample_02_medium.jpg"), + &Path::new("./test_images/sample_02_small.jpg")]; + let sample_02_hashes: [u64; 3] = [11009829669713008949, + 11009829670249879861, + 11009829669713008949]; + test_imageset_hash(hash::HashType::DHash, + hash::Precision::Medium, + sample_02_images, + sample_02_hashes); + + // Sample_03 tests + let sample_03_images: [&Path; 3] = [&Path::new("./test_images/sample_03_large.jpg"), + &Path::new("./test_images/sample_03_medium.jpg"), + &Path::new("./test_images/sample_03_small.jpg")]; + let sample_03_hashes: [u64; 3] = [225528496439353286, + 225528496439353286, + 226654396346195908]; + test_imageset_hash(hash::HashType::DHash, + hash::Precision::Medium, + sample_03_images, + sample_03_hashes); + + // Sample_04 tests + let sample_04_images: [&Path; 3] = [&Path::new("./test_images/sample_04_large.jpg"), + &Path::new("./test_images/sample_04_medium.jpg"), + &Path::new("./test_images/sample_04_small.jpg")]; + let sample_04_hashes: [u64; 3] = [14620651386429567209, + 14620651386429567209, + 14620651386429567209]; + test_imageset_hash(hash::HashType::DHash, + hash::Precision::Medium, + sample_04_images, + sample_04_hashes); + + // Clean_Cache + // super::teardown(); + } + + #[test] + fn test_confirm_phash_results() { + // Prep_Cache + super::init(); + + // Sample_01 tests + let sample_01_images: [&Path; 3] = [&Path::new("./test_images/sample_01_large.jpg"), + &Path::new("./test_images/sample_01_medium.jpg"), + &Path::new("./test_images/sample_01_small.jpg")]; + let sample_01_hashes: [u64; 3] = [72357778504597504, 72357778504597504, 72357778504597504]; + test_imageset_hash(hash::HashType::PHash, + hash::Precision::Medium, + sample_01_images, + sample_01_hashes); + + // Sample_02 tests + let sample_02_images: [&Path; 3] = [&Path::new("./test_images/sample_02_large.jpg"), + &Path::new("./test_images/sample_02_medium.jpg"), + &Path::new("./test_images/sample_02_small.jpg")]; + let sample_02_hashes: [u64; 3] = [5332332327550844928, + 5332332327550844928, + 5332332327550844928]; + test_imageset_hash(hash::HashType::PHash, + hash::Precision::Medium, + sample_02_images, + sample_02_hashes); + + // Sample_03 tests + let sample_03_images: [&Path; 3] = [&Path::new("./test_images/sample_03_large.jpg"), + &Path::new("./test_images/sample_03_medium.jpg"), + &Path::new("./test_images/sample_03_small.jpg")]; + let sample_03_hashes: [u64; 3] = [6917529027641081856, + 6917529027641081856, + 6917529027641081856]; + test_imageset_hash(hash::HashType::PHash, + hash::Precision::Medium, + sample_03_images, + sample_03_hashes); + + // Sample_04 tests + let sample_04_images: [&Path; 3] = [&Path::new("./test_images/sample_04_large.jpg"), + &Path::new("./test_images/sample_04_medium.jpg"), + &Path::new("./test_images/sample_04_small.jpg")]; + let sample_04_hashes: [u64; 3] = [10997931646002397184, + 10997931646002397184, + 11142046834078253056]; + test_imageset_hash(hash::HashType::PHash, + hash::Precision::Medium, + sample_04_images, + sample_04_hashes); + + // Clean_Cache + // super::teardown(); + } +} diff --git a/src/main.rs b/src/main.rs index 3ceadea..a23d032 100644 --- a/src/main.rs +++ b/src/main.rs @@ -42,7 +42,7 @@ fn main() { let args: Args = Docopt::new(USAGE) .and_then(|d| d.decode()) .unwrap_or_else(|e| e.exit()); - + // Print version information and exit if args.flag_version { println!("Perceptual Image Hashing: v{}", VERSION); @@ -66,11 +66,10 @@ fn main() { dhash: {} phash: {} "#, - hashes.orig_path, - hashes.ahash, - hashes.dhash, - hashes.phash - ); + hashes.orig_path, + hashes.ahash, + hashes.dhash, + hashes.phash); println!("{}", hash_result); } // Otherwise process only specific hashes