diff --git a/src/hash.rs b/src/hash.rs index 0801731..f753c70 100644 --- a/src/hash.rs +++ b/src/hash.rs @@ -36,6 +36,34 @@ pub struct PerceptualHashes<'a> { pub phash: u64 } +/** + * All the supported precision types + */ +pub enum Precision { + Low, + Medium, + High, +} + +impl Precision { + fn get_size(&self) -> u32 { + match *self { + Precision::Low => 4, + Precision::Medium => 8, + Precision::High => 16, + } + } +} + +/** + * Types of hashes supported + */ +pub enum HashType { + Ahash, + Dhash, + Phash +} + /** * Resonsible for parsing a path, converting an image and package it to be * hashed. @@ -50,8 +78,12 @@ pub struct PerceptualHashes<'a> { * A PreparedImage struct with the required information for performing hashing * */ -pub fn prepare_image(path: &Path, size: u32) -> PreparedImage { +pub fn prepare_image<'a>(path: &'a Path, hash_type: &HashType, precision: &Precision) -> PreparedImage<'a> { let image_path = path.to_str().unwrap(); + let size: u32 = match *hash_type { + HashType::Phash => precision.get_size() * 4, + _ => precision.get_size() + }; // Check if we have the already converted image in a cache and use that if possible. match cache::get_from_cache(&path, size) { Some(image) => { @@ -71,12 +103,12 @@ pub fn prepare_image(path: &Path, size: u32) -> PreparedImage { /** * Get all perceptual hashes for an image */ -pub fn get_perceptual_hashes(path: &Path, size: u32) -> PerceptualHashes { +pub fn get_perceptual_hashes<'a>(path: &'a Path, precision: &Precision) -> PerceptualHashes<'a> { let image_path = path.to_str().unwrap(); - let prepared_image = prepare_image(path, size); + let prepared_image = prepare_image(path, &HashType::Ahash, &precision); // phash uses a DFT, so it needs an image 4 times larger to work with for // the same precision of hash. That said, this hash is much more accurate. - let phash_prepared_image = prepare_image(path, size*4); + let phash_prepared_image = prepare_image(path, &HashType::Phash, &precision); let ahash = get_ahash(&prepared_image); let dhash = get_dhash(&prepared_image); let phash = get_phash(&phash_prepared_image); diff --git a/src/lib.rs b/src/lib.rs index 7d988ad..4669526 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -21,19 +21,19 @@ pub fn init() { } pub fn get_phashes(path: &Path) -> hash::PerceptualHashes { - hash::get_perceptual_hashes(path, 8) + hash::get_perceptual_hashes(path, &hash::Precision::Medium) } pub fn get_ahash(path: &Path) -> u64 { - hash::get_ahash(&hash::prepare_image(path, 8)) + hash::get_ahash(&hash::prepare_image(path, &hash::HashType::Ahash, &hash::Precision::Medium)) } pub fn get_dhash(path: &Path) -> u64 { - hash::get_dhash(&hash::prepare_image(path, 8)) + hash::get_dhash(&hash::prepare_image(path, &hash::HashType::Dhash, &hash::Precision::Medium)) } pub fn get_phash(path: &Path) -> u64 { - hash::get_phash(&hash::prepare_image(path, 32)) + hash::get_phash(&hash::prepare_image(path, &hash::HashType::Phash, &hash::Precision::Medium)) } pub fn get_hamming_distance(hash1: u64, hash2: u64) -> u64 { @@ -49,6 +49,7 @@ mod tests { use super::*; use std::fs; use std::path; + use std::clone::Clone; use hash; #[test] @@ -80,7 +81,8 @@ mod tests { // that are organized in the fashion of large->medium->small fn test_imageset_hash u64>( hash_func: F, - resize_target: u32, + hash_type: hash::HashType, + precision: hash::Precision, large_path: &str, medium_path: &str, small_path: &str, @@ -91,9 +93,9 @@ mod tests { expected_large_small_hamming: u64, expected_medium_small_hamming: u64) { - let large_prepared_image = hash::prepare_image(path::Path::new(large_path), resize_target); - let medium_prepared_image = hash::prepare_image(path::Path::new(medium_path), resize_target); - let small_prepared_image = hash::prepare_image(path::Path::new(small_path), resize_target); + let large_prepared_image = hash::prepare_image(path::Path::new(large_path), &hash_type, &precision); + let medium_prepared_image = hash::prepare_image(path::Path::new(medium_path), &hash_type, &precision); + let small_prepared_image = hash::prepare_image(path::Path::new(small_path), &hash_type, &precision); let actual_large_hash = hash_func(&large_prepared_image); let actual_medium_hash = hash_func(&medium_prepared_image); @@ -128,7 +130,8 @@ mod tests { // Sample_01 tests test_imageset_hash( hash::get_ahash, - 8u32, + hash::HashType::Ahash, + hash::Precision::Medium, "./test_images/sample_01_large.jpg", "./test_images/sample_01_medium.jpg", "./test_images/sample_01_small.jpg", @@ -143,7 +146,8 @@ mod tests { // Sample_02 tests test_imageset_hash( hash::get_ahash, - 8u32, + hash::HashType::Ahash, + hash::Precision::Medium, "./test_images/sample_02_large.jpg", "./test_images/sample_02_medium.jpg", "./test_images/sample_02_small.jpg", @@ -157,7 +161,8 @@ mod tests { // Sample_03 tests test_imageset_hash( hash::get_ahash, - 8u32, + hash::HashType::Ahash, + hash::Precision::Medium, "./test_images/sample_03_large.jpg", "./test_images/sample_03_medium.jpg", "./test_images/sample_03_small.jpg", @@ -172,7 +177,8 @@ mod tests { // Sample_04 tests test_imageset_hash( hash::get_ahash, - 8u32, + hash::HashType::Ahash, + hash::Precision::Medium, "./test_images/sample_04_large.jpg", "./test_images/sample_04_medium.jpg", "./test_images/sample_04_small.jpg", @@ -190,7 +196,8 @@ mod tests { // Sample_01 tests test_imageset_hash( hash::get_dhash, - 8u32, + hash::HashType::Dhash, + hash::Precision::Medium, "./test_images/sample_01_large.jpg", "./test_images/sample_01_medium.jpg", "./test_images/sample_01_small.jpg", @@ -205,7 +212,8 @@ mod tests { // Sample_02 tests test_imageset_hash( hash::get_dhash, - 8u32, + hash::HashType::Dhash, + hash::Precision::Medium, "./test_images/sample_02_large.jpg", "./test_images/sample_02_medium.jpg", "./test_images/sample_02_small.jpg", @@ -219,7 +227,8 @@ mod tests { // Sample_03 tests test_imageset_hash( hash::get_dhash, - 8u32, + hash::HashType::Dhash, + hash::Precision::Medium, "./test_images/sample_03_large.jpg", "./test_images/sample_03_medium.jpg", "./test_images/sample_03_small.jpg", @@ -234,7 +243,8 @@ mod tests { // Sample_04 tests test_imageset_hash( hash::get_dhash, - 8u32, + hash::HashType::Dhash, + hash::Precision::Medium, "./test_images/sample_04_large.jpg", "./test_images/sample_04_medium.jpg", "./test_images/sample_04_small.jpg", @@ -252,7 +262,8 @@ mod tests { // Sample_01 tests test_imageset_hash( hash::get_phash, - 32u32, + hash::HashType::Phash, + hash::Precision::Medium, "./test_images/sample_01_large.jpg", "./test_images/sample_01_medium.jpg", "./test_images/sample_01_small.jpg", @@ -267,7 +278,8 @@ mod tests { // Sample_02 tests test_imageset_hash( hash::get_phash, - 32u32, + hash::HashType::Phash, + hash::Precision::Medium, "./test_images/sample_02_large.jpg", "./test_images/sample_02_medium.jpg", "./test_images/sample_02_small.jpg", @@ -281,7 +293,8 @@ mod tests { // Sample_03 tests test_imageset_hash( hash::get_phash, - 32u32, + hash::HashType::Phash, + hash::Precision::Medium, "./test_images/sample_03_large.jpg", "./test_images/sample_03_medium.jpg", "./test_images/sample_03_small.jpg", @@ -296,7 +309,8 @@ mod tests { // Sample_04 tests test_imageset_hash( hash::get_phash, - 32u32, + hash::HashType::Phash, + hash::Precision::Medium, "./test_images/sample_04_large.jpg", "./test_images/sample_04_medium.jpg", "./test_images/sample_04_small.jpg",