Skip to content

Instantly share code, notes, and snippets.

@jstepien
Created February 5, 2018 10:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jstepien/d38f84a01feedbc8d3861185ad6a7f11 to your computer and use it in GitHub Desktop.
Save jstepien/d38f84a01feedbc8d3861185ad6a7f11 to your computer and use it in GitHub Desktop.
That looks oddly familiar

In which Rust and perceptual hashing come together.

[package]
name = "phash"
version = "0.1.0"
authors = ["Jan Stępień"]
[dependencies]
libc = "0.2.36"
rayon = "0.9.0"
extern crate libc;
extern crate rayon;
use std::env;
use std::ffi::CString;
use libc::{uint64_t, c_char, c_int};
use rayon::prelude::*;
#[link(name = "pHash")]
extern {
fn ph_dct_imagehash(
file: *const c_char,
hash: *mut uint64_t
) -> c_int;
}
fn imagehash(file: &str) -> Option<u64> {
let mut hash: u64 = 0;
let cstr = CString::new(file).unwrap();
unsafe {
let ptr = cstr.as_ptr();
match ph_dct_imagehash(ptr, &mut hash) {
0 => Some(hash),
_ => None,
}
}
}
fn main() {
let files: Vec<_> = env::args().skip(1).collect();
files.par_iter().for_each(|file| {
match imagehash(&file) {
Some(hash) => println!("{:016x} {}", hash, file),
None => eprintln!("Failed to hash {}", file),
}
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment