pub struct EdgeHashGenerator { /* private fields */ }Expand description
The PhotoDNA Edge Hash Generator library wrapper.
This struct handles loading the native library and provides access to all library functions through type-safe function pointers.
§Example
use photodna_sys::*;
let lib = EdgeHashGenerator::new(None, 4)?;
println!("Library version: {}", lib.library_version_text());Implementations§
Source§impl EdgeHashGenerator
impl EdgeHashGenerator
Sourcepub fn new(library_dir: Option<&str>, max_threads: i32) -> Result<Self, String>
pub fn new(library_dir: Option<&str>, max_threads: i32) -> Result<Self, String>
Creates a new EdgeHashGenerator by loading the native library.
§Parameters
library_dir: Directory containing the library. IfNone, uses [PHOTODNA_LIB_DIR].max_threads: Maximum number of concurrent threads. Calls exceeding this will block until a previous call completes.
§Returns
A Result containing the EdgeHashGenerator or an error message.
§Example
// Use default library path
let lib = EdgeHashGenerator::new(None, 4)?;
// Use custom library path
let lib = EdgeHashGenerator::new(Some("/path/to/libs"), 4)?;Examples found in repository?
12fn main() {
13 println!("PhotoDNA-sys Example");
14 println!("====================");
15 println!();
16
17 // SDK paths only available on native targets where SDK was present at build time
18 #[cfg(all(
19 any(target_os = "windows", target_os = "linux", target_os = "macos"),
20 not(photodna_no_sdk)
21 ))]
22 {
23 println!("SDK Root: {}", PHOTODNA_SDK_ROOT);
24 println!("Library Directory: {}", PHOTODNA_LIB_DIR);
25 println!();
26 }
27
28 #[cfg(any(
29 not(any(target_os = "windows", target_os = "linux", target_os = "macos")),
30 photodna_no_sdk
31 ))]
32 {
33 println!("SDK paths not available (build without SDK or BSD/WASM-only build)");
34 println!();
35 }
36
37 #[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
38 {
39 println!("Attempting to load PhotoDNA library...");
40
41 match EdgeHashGenerator::new(None, 4) {
42 Ok(lib) => {
43 println!("✓ Library loaded successfully!");
44 println!();
45 println!("Library Version Information:");
46 println!(" Version (packed): 0x{:08x}", lib.library_version());
47 println!(" Major: {}", lib.library_version_major());
48 println!(" Minor: {}", lib.library_version_minor());
49 println!(" Patch: {}", lib.library_version_patch());
50 if let Some(text) = lib.library_version_text() {
51 println!(" Text: {}", text);
52 }
53 println!();
54 println!("Hash sizes:");
55 println!(" Edge V2 (binary): {} bytes", PHOTODNA_HASH_SIZE_EDGE_V2);
56 println!(
57 " Edge V2 (base64): {} bytes",
58 PHOTODNA_HASH_SIZE_EDGE_V2_BASE64
59 );
60 }
61 Err(e) => {
62 eprintln!("✗ Failed to load library: {}", e);
63 std::process::exit(1);
64 }
65 }
66 }
67
68 #[cfg(not(any(target_os = "windows", target_os = "linux", target_os = "macos")))]
69 {
70 println!("Native library not available on this platform.");
71 println!("Use the 'wasm' feature with a WASM runtime for BSD platforms.");
72 }
73}More examples
12fn main() {
13 println!("PhotoDNA Hash Computation Example");
14 println!("==================================");
15 println!();
16
17 #[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
18 {
19 // Load the library
20 let lib = match EdgeHashGenerator::new(None, 4) {
21 Ok(lib) => {
22 println!(
23 "✓ Library loaded: version {}",
24 lib.library_version_text().unwrap_or("unknown")
25 );
26 lib
27 }
28 Err(e) => {
29 eprintln!("✗ Failed to load library: {}", e);
30 std::process::exit(1);
31 }
32 };
33
34 // Create a simple test image (gradient pattern)
35 // Images must be at least 50x50 pixels
36 let width = 100;
37 let height = 100;
38 let bytes_per_pixel = 3; // RGB format
39 let stride = width * bytes_per_pixel;
40
41 // Generate a simple gradient image
42 let mut image_data = vec![0u8; (height * stride) as usize];
43 for y in 0..height {
44 for x in 0..width {
45 let offset = ((y * stride) + (x * bytes_per_pixel)) as usize;
46 // Create a diagonal gradient pattern
47 let r = ((x * 255) / width) as u8;
48 let g = ((y * 255) / height) as u8;
49 let b = (((x + y) * 255) / (width + height)) as u8;
50 image_data[offset] = r;
51 image_data[offset + 1] = g;
52 image_data[offset + 2] = b;
53 }
54 }
55
56 println!(
57 "Created test image: {}x{} RGB ({} bytes)",
58 width,
59 height,
60 image_data.len()
61 );
62 println!();
63
64 // Compute the hash
65 let mut hash = [0u8; PHOTODNA_HASH_SIZE_MAX];
66
67 let result = unsafe {
68 lib.photo_dna_edge_hash(
69 image_data.as_ptr(),
70 hash.as_mut_ptr(),
71 width,
72 height,
73 stride,
74 PhotoDna_Default | PhotoDna_Rgb,
75 )
76 };
77
78 if result < 0 {
79 eprintln!(
80 "✗ Hash computation failed: {} (code {})",
81 error_code_description(result),
82 result
83 );
84 if let Some(lib_msg) = lib.get_error_string(result) {
85 eprintln!(" Library message: {}", lib_msg);
86 }
87 std::process::exit(1);
88 }
89
90 println!("✓ Hash computed successfully!");
91 println!();
92
93 // Display first 32 bytes of hash in hex
94 let hash_preview: String = hash[..32]
95 .iter()
96 .map(|b| format!("{:02x}", b))
97 .collect::<Vec<_>>()
98 .join(" ");
99
100 println!("Hash (first 32 bytes): {}", hash_preview);
101 println!("Hash size: {} bytes", PHOTODNA_HASH_SIZE_EDGE_V2);
102
103 // Also demonstrate border detection
104 println!();
105 println!("Testing border detection...");
106
107 let mut hash_results = [HashResult::default(); 2];
108
109 let border_result = unsafe {
110 lib.photo_dna_edge_hash_border(
111 image_data.as_ptr(),
112 hash_results.as_mut_ptr(),
113 2,
114 width,
115 height,
116 stride,
117 PhotoDna_Default | PhotoDna_Rgb,
118 )
119 };
120
121 if border_result < 0 {
122 println!(
123 "Border detection: {} (code {})",
124 error_code_description(border_result),
125 border_result
126 );
127 } else {
128 println!("Border detection returned {} hash(es)", border_result);
129 for i in 0..border_result as usize {
130 let result = hash_results[i].result;
131 let x = hash_results[i].header_dimensions_image_x;
132 let y = hash_results[i].header_dimensions_image_y;
133 let w = hash_results[i].header_dimensions_image_w;
134 let h = hash_results[i].header_dimensions_image_h;
135 println!(
136 " Hash {}: result={}, region=({},{},{},{})",
137 i, result, x, y, w, h
138 );
139 }
140 }
141 }
142
143 #[cfg(not(any(target_os = "windows", target_os = "linux", target_os = "macos")))]
144 {
145 println!("Native library not available on this platform.");
146 println!("Use the 'wasm' feature with a WASM runtime for BSD platforms.");
147 }
148}Sourcepub fn raw_instance(&self) -> *mut c_void
pub fn raw_instance(&self) -> *mut c_void
Returns the raw library instance handle.
§Safety
The returned pointer is only valid while this EdgeHashGenerator is alive.
Sourcepub fn get_error_number(&self) -> i32
pub fn get_error_number(&self) -> i32
Retrieves the last error number from the library.
Sourcepub fn get_error_string(&self, error: i32) -> Option<&str>
pub fn get_error_string(&self, error: i32) -> Option<&str>
Returns a human-readable description for an error code.
Returns None if the error code is unknown.
Examples found in repository?
12fn main() {
13 println!("PhotoDNA Hash Computation Example");
14 println!("==================================");
15 println!();
16
17 #[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
18 {
19 // Load the library
20 let lib = match EdgeHashGenerator::new(None, 4) {
21 Ok(lib) => {
22 println!(
23 "✓ Library loaded: version {}",
24 lib.library_version_text().unwrap_or("unknown")
25 );
26 lib
27 }
28 Err(e) => {
29 eprintln!("✗ Failed to load library: {}", e);
30 std::process::exit(1);
31 }
32 };
33
34 // Create a simple test image (gradient pattern)
35 // Images must be at least 50x50 pixels
36 let width = 100;
37 let height = 100;
38 let bytes_per_pixel = 3; // RGB format
39 let stride = width * bytes_per_pixel;
40
41 // Generate a simple gradient image
42 let mut image_data = vec![0u8; (height * stride) as usize];
43 for y in 0..height {
44 for x in 0..width {
45 let offset = ((y * stride) + (x * bytes_per_pixel)) as usize;
46 // Create a diagonal gradient pattern
47 let r = ((x * 255) / width) as u8;
48 let g = ((y * 255) / height) as u8;
49 let b = (((x + y) * 255) / (width + height)) as u8;
50 image_data[offset] = r;
51 image_data[offset + 1] = g;
52 image_data[offset + 2] = b;
53 }
54 }
55
56 println!(
57 "Created test image: {}x{} RGB ({} bytes)",
58 width,
59 height,
60 image_data.len()
61 );
62 println!();
63
64 // Compute the hash
65 let mut hash = [0u8; PHOTODNA_HASH_SIZE_MAX];
66
67 let result = unsafe {
68 lib.photo_dna_edge_hash(
69 image_data.as_ptr(),
70 hash.as_mut_ptr(),
71 width,
72 height,
73 stride,
74 PhotoDna_Default | PhotoDna_Rgb,
75 )
76 };
77
78 if result < 0 {
79 eprintln!(
80 "✗ Hash computation failed: {} (code {})",
81 error_code_description(result),
82 result
83 );
84 if let Some(lib_msg) = lib.get_error_string(result) {
85 eprintln!(" Library message: {}", lib_msg);
86 }
87 std::process::exit(1);
88 }
89
90 println!("✓ Hash computed successfully!");
91 println!();
92
93 // Display first 32 bytes of hash in hex
94 let hash_preview: String = hash[..32]
95 .iter()
96 .map(|b| format!("{:02x}", b))
97 .collect::<Vec<_>>()
98 .join(" ");
99
100 println!("Hash (first 32 bytes): {}", hash_preview);
101 println!("Hash size: {} bytes", PHOTODNA_HASH_SIZE_EDGE_V2);
102
103 // Also demonstrate border detection
104 println!();
105 println!("Testing border detection...");
106
107 let mut hash_results = [HashResult::default(); 2];
108
109 let border_result = unsafe {
110 lib.photo_dna_edge_hash_border(
111 image_data.as_ptr(),
112 hash_results.as_mut_ptr(),
113 2,
114 width,
115 height,
116 stride,
117 PhotoDna_Default | PhotoDna_Rgb,
118 )
119 };
120
121 if border_result < 0 {
122 println!(
123 "Border detection: {} (code {})",
124 error_code_description(border_result),
125 border_result
126 );
127 } else {
128 println!("Border detection returned {} hash(es)", border_result);
129 for i in 0..border_result as usize {
130 let result = hash_results[i].result;
131 let x = hash_results[i].header_dimensions_image_x;
132 let y = hash_results[i].header_dimensions_image_y;
133 let w = hash_results[i].header_dimensions_image_w;
134 let h = hash_results[i].header_dimensions_image_h;
135 println!(
136 " Hash {}: result={}, region=({},{},{},{})",
137 i, result, x, y, w, h
138 );
139 }
140 }
141 }
142
143 #[cfg(not(any(target_os = "windows", target_os = "linux", target_os = "macos")))]
144 {
145 println!("Native library not available on this platform.");
146 println!("Use the 'wasm' feature with a WASM runtime for BSD platforms.");
147 }
148}Sourcepub fn library_version(&self) -> i32
pub fn library_version(&self) -> i32
Returns the library version as a packed integer.
High 16 bits = major, low 16 bits = minor.
Examples found in repository?
12fn main() {
13 println!("PhotoDNA-sys Example");
14 println!("====================");
15 println!();
16
17 // SDK paths only available on native targets where SDK was present at build time
18 #[cfg(all(
19 any(target_os = "windows", target_os = "linux", target_os = "macos"),
20 not(photodna_no_sdk)
21 ))]
22 {
23 println!("SDK Root: {}", PHOTODNA_SDK_ROOT);
24 println!("Library Directory: {}", PHOTODNA_LIB_DIR);
25 println!();
26 }
27
28 #[cfg(any(
29 not(any(target_os = "windows", target_os = "linux", target_os = "macos")),
30 photodna_no_sdk
31 ))]
32 {
33 println!("SDK paths not available (build without SDK or BSD/WASM-only build)");
34 println!();
35 }
36
37 #[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
38 {
39 println!("Attempting to load PhotoDNA library...");
40
41 match EdgeHashGenerator::new(None, 4) {
42 Ok(lib) => {
43 println!("✓ Library loaded successfully!");
44 println!();
45 println!("Library Version Information:");
46 println!(" Version (packed): 0x{:08x}", lib.library_version());
47 println!(" Major: {}", lib.library_version_major());
48 println!(" Minor: {}", lib.library_version_minor());
49 println!(" Patch: {}", lib.library_version_patch());
50 if let Some(text) = lib.library_version_text() {
51 println!(" Text: {}", text);
52 }
53 println!();
54 println!("Hash sizes:");
55 println!(" Edge V2 (binary): {} bytes", PHOTODNA_HASH_SIZE_EDGE_V2);
56 println!(
57 " Edge V2 (base64): {} bytes",
58 PHOTODNA_HASH_SIZE_EDGE_V2_BASE64
59 );
60 }
61 Err(e) => {
62 eprintln!("✗ Failed to load library: {}", e);
63 std::process::exit(1);
64 }
65 }
66 }
67
68 #[cfg(not(any(target_os = "windows", target_os = "linux", target_os = "macos")))]
69 {
70 println!("Native library not available on this platform.");
71 println!("Use the 'wasm' feature with a WASM runtime for BSD platforms.");
72 }
73}Sourcepub fn library_version_major(&self) -> i32
pub fn library_version_major(&self) -> i32
Returns the major version number.
Examples found in repository?
12fn main() {
13 println!("PhotoDNA-sys Example");
14 println!("====================");
15 println!();
16
17 // SDK paths only available on native targets where SDK was present at build time
18 #[cfg(all(
19 any(target_os = "windows", target_os = "linux", target_os = "macos"),
20 not(photodna_no_sdk)
21 ))]
22 {
23 println!("SDK Root: {}", PHOTODNA_SDK_ROOT);
24 println!("Library Directory: {}", PHOTODNA_LIB_DIR);
25 println!();
26 }
27
28 #[cfg(any(
29 not(any(target_os = "windows", target_os = "linux", target_os = "macos")),
30 photodna_no_sdk
31 ))]
32 {
33 println!("SDK paths not available (build without SDK or BSD/WASM-only build)");
34 println!();
35 }
36
37 #[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
38 {
39 println!("Attempting to load PhotoDNA library...");
40
41 match EdgeHashGenerator::new(None, 4) {
42 Ok(lib) => {
43 println!("✓ Library loaded successfully!");
44 println!();
45 println!("Library Version Information:");
46 println!(" Version (packed): 0x{:08x}", lib.library_version());
47 println!(" Major: {}", lib.library_version_major());
48 println!(" Minor: {}", lib.library_version_minor());
49 println!(" Patch: {}", lib.library_version_patch());
50 if let Some(text) = lib.library_version_text() {
51 println!(" Text: {}", text);
52 }
53 println!();
54 println!("Hash sizes:");
55 println!(" Edge V2 (binary): {} bytes", PHOTODNA_HASH_SIZE_EDGE_V2);
56 println!(
57 " Edge V2 (base64): {} bytes",
58 PHOTODNA_HASH_SIZE_EDGE_V2_BASE64
59 );
60 }
61 Err(e) => {
62 eprintln!("✗ Failed to load library: {}", e);
63 std::process::exit(1);
64 }
65 }
66 }
67
68 #[cfg(not(any(target_os = "windows", target_os = "linux", target_os = "macos")))]
69 {
70 println!("Native library not available on this platform.");
71 println!("Use the 'wasm' feature with a WASM runtime for BSD platforms.");
72 }
73}Sourcepub fn library_version_minor(&self) -> i32
pub fn library_version_minor(&self) -> i32
Returns the minor version number.
Examples found in repository?
12fn main() {
13 println!("PhotoDNA-sys Example");
14 println!("====================");
15 println!();
16
17 // SDK paths only available on native targets where SDK was present at build time
18 #[cfg(all(
19 any(target_os = "windows", target_os = "linux", target_os = "macos"),
20 not(photodna_no_sdk)
21 ))]
22 {
23 println!("SDK Root: {}", PHOTODNA_SDK_ROOT);
24 println!("Library Directory: {}", PHOTODNA_LIB_DIR);
25 println!();
26 }
27
28 #[cfg(any(
29 not(any(target_os = "windows", target_os = "linux", target_os = "macos")),
30 photodna_no_sdk
31 ))]
32 {
33 println!("SDK paths not available (build without SDK or BSD/WASM-only build)");
34 println!();
35 }
36
37 #[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
38 {
39 println!("Attempting to load PhotoDNA library...");
40
41 match EdgeHashGenerator::new(None, 4) {
42 Ok(lib) => {
43 println!("✓ Library loaded successfully!");
44 println!();
45 println!("Library Version Information:");
46 println!(" Version (packed): 0x{:08x}", lib.library_version());
47 println!(" Major: {}", lib.library_version_major());
48 println!(" Minor: {}", lib.library_version_minor());
49 println!(" Patch: {}", lib.library_version_patch());
50 if let Some(text) = lib.library_version_text() {
51 println!(" Text: {}", text);
52 }
53 println!();
54 println!("Hash sizes:");
55 println!(" Edge V2 (binary): {} bytes", PHOTODNA_HASH_SIZE_EDGE_V2);
56 println!(
57 " Edge V2 (base64): {} bytes",
58 PHOTODNA_HASH_SIZE_EDGE_V2_BASE64
59 );
60 }
61 Err(e) => {
62 eprintln!("✗ Failed to load library: {}", e);
63 std::process::exit(1);
64 }
65 }
66 }
67
68 #[cfg(not(any(target_os = "windows", target_os = "linux", target_os = "macos")))]
69 {
70 println!("Native library not available on this platform.");
71 println!("Use the 'wasm' feature with a WASM runtime for BSD platforms.");
72 }
73}Sourcepub fn library_version_patch(&self) -> i32
pub fn library_version_patch(&self) -> i32
Returns the patch version number.
Examples found in repository?
12fn main() {
13 println!("PhotoDNA-sys Example");
14 println!("====================");
15 println!();
16
17 // SDK paths only available on native targets where SDK was present at build time
18 #[cfg(all(
19 any(target_os = "windows", target_os = "linux", target_os = "macos"),
20 not(photodna_no_sdk)
21 ))]
22 {
23 println!("SDK Root: {}", PHOTODNA_SDK_ROOT);
24 println!("Library Directory: {}", PHOTODNA_LIB_DIR);
25 println!();
26 }
27
28 #[cfg(any(
29 not(any(target_os = "windows", target_os = "linux", target_os = "macos")),
30 photodna_no_sdk
31 ))]
32 {
33 println!("SDK paths not available (build without SDK or BSD/WASM-only build)");
34 println!();
35 }
36
37 #[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
38 {
39 println!("Attempting to load PhotoDNA library...");
40
41 match EdgeHashGenerator::new(None, 4) {
42 Ok(lib) => {
43 println!("✓ Library loaded successfully!");
44 println!();
45 println!("Library Version Information:");
46 println!(" Version (packed): 0x{:08x}", lib.library_version());
47 println!(" Major: {}", lib.library_version_major());
48 println!(" Minor: {}", lib.library_version_minor());
49 println!(" Patch: {}", lib.library_version_patch());
50 if let Some(text) = lib.library_version_text() {
51 println!(" Text: {}", text);
52 }
53 println!();
54 println!("Hash sizes:");
55 println!(" Edge V2 (binary): {} bytes", PHOTODNA_HASH_SIZE_EDGE_V2);
56 println!(
57 " Edge V2 (base64): {} bytes",
58 PHOTODNA_HASH_SIZE_EDGE_V2_BASE64
59 );
60 }
61 Err(e) => {
62 eprintln!("✗ Failed to load library: {}", e);
63 std::process::exit(1);
64 }
65 }
66 }
67
68 #[cfg(not(any(target_os = "windows", target_os = "linux", target_os = "macos")))]
69 {
70 println!("Native library not available on this platform.");
71 println!("Use the 'wasm' feature with a WASM runtime for BSD platforms.");
72 }
73}Sourcepub fn library_version_text(&self) -> Option<&str>
pub fn library_version_text(&self) -> Option<&str>
Returns the library version as a human-readable string.
Examples found in repository?
12fn main() {
13 println!("PhotoDNA-sys Example");
14 println!("====================");
15 println!();
16
17 // SDK paths only available on native targets where SDK was present at build time
18 #[cfg(all(
19 any(target_os = "windows", target_os = "linux", target_os = "macos"),
20 not(photodna_no_sdk)
21 ))]
22 {
23 println!("SDK Root: {}", PHOTODNA_SDK_ROOT);
24 println!("Library Directory: {}", PHOTODNA_LIB_DIR);
25 println!();
26 }
27
28 #[cfg(any(
29 not(any(target_os = "windows", target_os = "linux", target_os = "macos")),
30 photodna_no_sdk
31 ))]
32 {
33 println!("SDK paths not available (build without SDK or BSD/WASM-only build)");
34 println!();
35 }
36
37 #[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
38 {
39 println!("Attempting to load PhotoDNA library...");
40
41 match EdgeHashGenerator::new(None, 4) {
42 Ok(lib) => {
43 println!("✓ Library loaded successfully!");
44 println!();
45 println!("Library Version Information:");
46 println!(" Version (packed): 0x{:08x}", lib.library_version());
47 println!(" Major: {}", lib.library_version_major());
48 println!(" Minor: {}", lib.library_version_minor());
49 println!(" Patch: {}", lib.library_version_patch());
50 if let Some(text) = lib.library_version_text() {
51 println!(" Text: {}", text);
52 }
53 println!();
54 println!("Hash sizes:");
55 println!(" Edge V2 (binary): {} bytes", PHOTODNA_HASH_SIZE_EDGE_V2);
56 println!(
57 " Edge V2 (base64): {} bytes",
58 PHOTODNA_HASH_SIZE_EDGE_V2_BASE64
59 );
60 }
61 Err(e) => {
62 eprintln!("✗ Failed to load library: {}", e);
63 std::process::exit(1);
64 }
65 }
66 }
67
68 #[cfg(not(any(target_os = "windows", target_os = "linux", target_os = "macos")))]
69 {
70 println!("Native library not available on this platform.");
71 println!("Use the 'wasm' feature with a WASM runtime for BSD platforms.");
72 }
73}More examples
12fn main() {
13 println!("PhotoDNA Hash Computation Example");
14 println!("==================================");
15 println!();
16
17 #[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
18 {
19 // Load the library
20 let lib = match EdgeHashGenerator::new(None, 4) {
21 Ok(lib) => {
22 println!(
23 "✓ Library loaded: version {}",
24 lib.library_version_text().unwrap_or("unknown")
25 );
26 lib
27 }
28 Err(e) => {
29 eprintln!("✗ Failed to load library: {}", e);
30 std::process::exit(1);
31 }
32 };
33
34 // Create a simple test image (gradient pattern)
35 // Images must be at least 50x50 pixels
36 let width = 100;
37 let height = 100;
38 let bytes_per_pixel = 3; // RGB format
39 let stride = width * bytes_per_pixel;
40
41 // Generate a simple gradient image
42 let mut image_data = vec![0u8; (height * stride) as usize];
43 for y in 0..height {
44 for x in 0..width {
45 let offset = ((y * stride) + (x * bytes_per_pixel)) as usize;
46 // Create a diagonal gradient pattern
47 let r = ((x * 255) / width) as u8;
48 let g = ((y * 255) / height) as u8;
49 let b = (((x + y) * 255) / (width + height)) as u8;
50 image_data[offset] = r;
51 image_data[offset + 1] = g;
52 image_data[offset + 2] = b;
53 }
54 }
55
56 println!(
57 "Created test image: {}x{} RGB ({} bytes)",
58 width,
59 height,
60 image_data.len()
61 );
62 println!();
63
64 // Compute the hash
65 let mut hash = [0u8; PHOTODNA_HASH_SIZE_MAX];
66
67 let result = unsafe {
68 lib.photo_dna_edge_hash(
69 image_data.as_ptr(),
70 hash.as_mut_ptr(),
71 width,
72 height,
73 stride,
74 PhotoDna_Default | PhotoDna_Rgb,
75 )
76 };
77
78 if result < 0 {
79 eprintln!(
80 "✗ Hash computation failed: {} (code {})",
81 error_code_description(result),
82 result
83 );
84 if let Some(lib_msg) = lib.get_error_string(result) {
85 eprintln!(" Library message: {}", lib_msg);
86 }
87 std::process::exit(1);
88 }
89
90 println!("✓ Hash computed successfully!");
91 println!();
92
93 // Display first 32 bytes of hash in hex
94 let hash_preview: String = hash[..32]
95 .iter()
96 .map(|b| format!("{:02x}", b))
97 .collect::<Vec<_>>()
98 .join(" ");
99
100 println!("Hash (first 32 bytes): {}", hash_preview);
101 println!("Hash size: {} bytes", PHOTODNA_HASH_SIZE_EDGE_V2);
102
103 // Also demonstrate border detection
104 println!();
105 println!("Testing border detection...");
106
107 let mut hash_results = [HashResult::default(); 2];
108
109 let border_result = unsafe {
110 lib.photo_dna_edge_hash_border(
111 image_data.as_ptr(),
112 hash_results.as_mut_ptr(),
113 2,
114 width,
115 height,
116 stride,
117 PhotoDna_Default | PhotoDna_Rgb,
118 )
119 };
120
121 if border_result < 0 {
122 println!(
123 "Border detection: {} (code {})",
124 error_code_description(border_result),
125 border_result
126 );
127 } else {
128 println!("Border detection returned {} hash(es)", border_result);
129 for i in 0..border_result as usize {
130 let result = hash_results[i].result;
131 let x = hash_results[i].header_dimensions_image_x;
132 let y = hash_results[i].header_dimensions_image_y;
133 let w = hash_results[i].header_dimensions_image_w;
134 let h = hash_results[i].header_dimensions_image_h;
135 println!(
136 " Hash {}: result={}, region=({},{},{},{})",
137 i, result, x, y, w, h
138 );
139 }
140 }
141 }
142
143 #[cfg(not(any(target_os = "windows", target_os = "linux", target_os = "macos")))]
144 {
145 println!("Native library not available on this platform.");
146 println!("Use the 'wasm' feature with a WASM runtime for BSD platforms.");
147 }
148}Sourcepub unsafe fn photo_dna_edge_hash(
&self,
image_data: *const u8,
hash_value: *mut u8,
width: i32,
height: i32,
stride: i32,
options: PhotoDnaOptions,
) -> i32
pub unsafe fn photo_dna_edge_hash( &self, image_data: *const u8, hash_value: *mut u8, width: i32, height: i32, stride: i32, options: PhotoDnaOptions, ) -> i32
Computes the PhotoDNA Edge Hash of an image.
§Parameters
image_data: Pointer to pixel data in the format specified byoptions.hash_value: Output buffer for the computed hash. Must be at leastPHOTODNA_HASH_SIZE_MAXbytes.width: Image width in pixels (minimum 50).height: Image height in pixels (minimum 50).stride: Row stride in bytes, or 0 to calculate from dimensions.options: Combination ofPhotoDnaOptionsflags.
§Returns
0 on success, or a negative error code.
§Safety
image_datamust point to valid pixel data of sizeheight * stridebytes.hash_valuemust point to a buffer of at leastPHOTODNA_HASH_SIZE_MAXbytes.
Examples found in repository?
12fn main() {
13 println!("PhotoDNA Hash Computation Example");
14 println!("==================================");
15 println!();
16
17 #[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
18 {
19 // Load the library
20 let lib = match EdgeHashGenerator::new(None, 4) {
21 Ok(lib) => {
22 println!(
23 "✓ Library loaded: version {}",
24 lib.library_version_text().unwrap_or("unknown")
25 );
26 lib
27 }
28 Err(e) => {
29 eprintln!("✗ Failed to load library: {}", e);
30 std::process::exit(1);
31 }
32 };
33
34 // Create a simple test image (gradient pattern)
35 // Images must be at least 50x50 pixels
36 let width = 100;
37 let height = 100;
38 let bytes_per_pixel = 3; // RGB format
39 let stride = width * bytes_per_pixel;
40
41 // Generate a simple gradient image
42 let mut image_data = vec![0u8; (height * stride) as usize];
43 for y in 0..height {
44 for x in 0..width {
45 let offset = ((y * stride) + (x * bytes_per_pixel)) as usize;
46 // Create a diagonal gradient pattern
47 let r = ((x * 255) / width) as u8;
48 let g = ((y * 255) / height) as u8;
49 let b = (((x + y) * 255) / (width + height)) as u8;
50 image_data[offset] = r;
51 image_data[offset + 1] = g;
52 image_data[offset + 2] = b;
53 }
54 }
55
56 println!(
57 "Created test image: {}x{} RGB ({} bytes)",
58 width,
59 height,
60 image_data.len()
61 );
62 println!();
63
64 // Compute the hash
65 let mut hash = [0u8; PHOTODNA_HASH_SIZE_MAX];
66
67 let result = unsafe {
68 lib.photo_dna_edge_hash(
69 image_data.as_ptr(),
70 hash.as_mut_ptr(),
71 width,
72 height,
73 stride,
74 PhotoDna_Default | PhotoDna_Rgb,
75 )
76 };
77
78 if result < 0 {
79 eprintln!(
80 "✗ Hash computation failed: {} (code {})",
81 error_code_description(result),
82 result
83 );
84 if let Some(lib_msg) = lib.get_error_string(result) {
85 eprintln!(" Library message: {}", lib_msg);
86 }
87 std::process::exit(1);
88 }
89
90 println!("✓ Hash computed successfully!");
91 println!();
92
93 // Display first 32 bytes of hash in hex
94 let hash_preview: String = hash[..32]
95 .iter()
96 .map(|b| format!("{:02x}", b))
97 .collect::<Vec<_>>()
98 .join(" ");
99
100 println!("Hash (first 32 bytes): {}", hash_preview);
101 println!("Hash size: {} bytes", PHOTODNA_HASH_SIZE_EDGE_V2);
102
103 // Also demonstrate border detection
104 println!();
105 println!("Testing border detection...");
106
107 let mut hash_results = [HashResult::default(); 2];
108
109 let border_result = unsafe {
110 lib.photo_dna_edge_hash_border(
111 image_data.as_ptr(),
112 hash_results.as_mut_ptr(),
113 2,
114 width,
115 height,
116 stride,
117 PhotoDna_Default | PhotoDna_Rgb,
118 )
119 };
120
121 if border_result < 0 {
122 println!(
123 "Border detection: {} (code {})",
124 error_code_description(border_result),
125 border_result
126 );
127 } else {
128 println!("Border detection returned {} hash(es)", border_result);
129 for i in 0..border_result as usize {
130 let result = hash_results[i].result;
131 let x = hash_results[i].header_dimensions_image_x;
132 let y = hash_results[i].header_dimensions_image_y;
133 let w = hash_results[i].header_dimensions_image_w;
134 let h = hash_results[i].header_dimensions_image_h;
135 println!(
136 " Hash {}: result={}, region=({},{},{},{})",
137 i, result, x, y, w, h
138 );
139 }
140 }
141 }
142
143 #[cfg(not(any(target_os = "windows", target_os = "linux", target_os = "macos")))]
144 {
145 println!("Native library not available on this platform.");
146 println!("Use the 'wasm' feature with a WASM runtime for BSD platforms.");
147 }
148}Sourcepub unsafe fn photo_dna_edge_hash_border(
&self,
image_data: *const u8,
hash_results: *mut HashResult,
max_hash_count: i32,
width: i32,
height: i32,
stride: i32,
options: PhotoDnaOptions,
) -> i32
pub unsafe fn photo_dna_edge_hash_border( &self, image_data: *const u8, hash_results: *mut HashResult, max_hash_count: i32, width: i32, height: i32, stride: i32, options: PhotoDnaOptions, ) -> i32
Computes the PhotoDNA Edge Hash with border detection.
Returns hashes for both the original image and the image with borders removed (if detected).
§Parameters
image_data: Pointer to pixel data in the format specified byoptions.hash_results: Output array for computed hashes (at least 2 entries).max_hash_count: Size of thehash_resultsarray.width: Image width in pixels (minimum 50).height: Image height in pixels (minimum 50).stride: Row stride in bytes, or 0 to calculate from dimensions.options: Combination ofPhotoDnaOptionsflags.
§Returns
Number of hashes returned (1 or 2), or a negative error code.
§Safety
image_datamust point to valid pixel data.hash_resultsmust point to an array of at leastmax_hash_countelements.
Examples found in repository?
12fn main() {
13 println!("PhotoDNA Hash Computation Example");
14 println!("==================================");
15 println!();
16
17 #[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
18 {
19 // Load the library
20 let lib = match EdgeHashGenerator::new(None, 4) {
21 Ok(lib) => {
22 println!(
23 "✓ Library loaded: version {}",
24 lib.library_version_text().unwrap_or("unknown")
25 );
26 lib
27 }
28 Err(e) => {
29 eprintln!("✗ Failed to load library: {}", e);
30 std::process::exit(1);
31 }
32 };
33
34 // Create a simple test image (gradient pattern)
35 // Images must be at least 50x50 pixels
36 let width = 100;
37 let height = 100;
38 let bytes_per_pixel = 3; // RGB format
39 let stride = width * bytes_per_pixel;
40
41 // Generate a simple gradient image
42 let mut image_data = vec![0u8; (height * stride) as usize];
43 for y in 0..height {
44 for x in 0..width {
45 let offset = ((y * stride) + (x * bytes_per_pixel)) as usize;
46 // Create a diagonal gradient pattern
47 let r = ((x * 255) / width) as u8;
48 let g = ((y * 255) / height) as u8;
49 let b = (((x + y) * 255) / (width + height)) as u8;
50 image_data[offset] = r;
51 image_data[offset + 1] = g;
52 image_data[offset + 2] = b;
53 }
54 }
55
56 println!(
57 "Created test image: {}x{} RGB ({} bytes)",
58 width,
59 height,
60 image_data.len()
61 );
62 println!();
63
64 // Compute the hash
65 let mut hash = [0u8; PHOTODNA_HASH_SIZE_MAX];
66
67 let result = unsafe {
68 lib.photo_dna_edge_hash(
69 image_data.as_ptr(),
70 hash.as_mut_ptr(),
71 width,
72 height,
73 stride,
74 PhotoDna_Default | PhotoDna_Rgb,
75 )
76 };
77
78 if result < 0 {
79 eprintln!(
80 "✗ Hash computation failed: {} (code {})",
81 error_code_description(result),
82 result
83 );
84 if let Some(lib_msg) = lib.get_error_string(result) {
85 eprintln!(" Library message: {}", lib_msg);
86 }
87 std::process::exit(1);
88 }
89
90 println!("✓ Hash computed successfully!");
91 println!();
92
93 // Display first 32 bytes of hash in hex
94 let hash_preview: String = hash[..32]
95 .iter()
96 .map(|b| format!("{:02x}", b))
97 .collect::<Vec<_>>()
98 .join(" ");
99
100 println!("Hash (first 32 bytes): {}", hash_preview);
101 println!("Hash size: {} bytes", PHOTODNA_HASH_SIZE_EDGE_V2);
102
103 // Also demonstrate border detection
104 println!();
105 println!("Testing border detection...");
106
107 let mut hash_results = [HashResult::default(); 2];
108
109 let border_result = unsafe {
110 lib.photo_dna_edge_hash_border(
111 image_data.as_ptr(),
112 hash_results.as_mut_ptr(),
113 2,
114 width,
115 height,
116 stride,
117 PhotoDna_Default | PhotoDna_Rgb,
118 )
119 };
120
121 if border_result < 0 {
122 println!(
123 "Border detection: {} (code {})",
124 error_code_description(border_result),
125 border_result
126 );
127 } else {
128 println!("Border detection returned {} hash(es)", border_result);
129 for i in 0..border_result as usize {
130 let result = hash_results[i].result;
131 let x = hash_results[i].header_dimensions_image_x;
132 let y = hash_results[i].header_dimensions_image_y;
133 let w = hash_results[i].header_dimensions_image_w;
134 let h = hash_results[i].header_dimensions_image_h;
135 println!(
136 " Hash {}: result={}, region=({},{},{},{})",
137 i, result, x, y, w, h
138 );
139 }
140 }
141 }
142
143 #[cfg(not(any(target_os = "windows", target_os = "linux", target_os = "macos")))]
144 {
145 println!("Native library not available on this platform.");
146 println!("Use the 'wasm' feature with a WASM runtime for BSD platforms.");
147 }
148}Sourcepub unsafe fn photo_dna_edge_hash_border_sub(
&self,
image_data: *const u8,
hash_results: *mut HashResult,
max_hash_count: i32,
width: i32,
height: i32,
stride: i32,
x: i32,
y: i32,
w: i32,
h: i32,
options: PhotoDnaOptions,
) -> i32
pub unsafe fn photo_dna_edge_hash_border_sub( &self, image_data: *const u8, hash_results: *mut HashResult, max_hash_count: i32, width: i32, height: i32, stride: i32, x: i32, y: i32, w: i32, h: i32, options: PhotoDnaOptions, ) -> i32
Computes the PhotoDNA Edge Hash for a sub-region with border detection.
§Safety
- All pointer parameters must be valid.
- The sub-region must be within the image bounds.
Sourcepub unsafe fn photo_dna_edge_hash_sub(
&self,
image_data: *const u8,
hash_value: *mut u8,
width: i32,
height: i32,
stride: i32,
x: i32,
y: i32,
w: i32,
h: i32,
options: PhotoDnaOptions,
) -> i32
pub unsafe fn photo_dna_edge_hash_sub( &self, image_data: *const u8, hash_value: *mut u8, width: i32, height: i32, stride: i32, x: i32, y: i32, w: i32, h: i32, options: PhotoDnaOptions, ) -> i32
Computes the PhotoDNA Edge Hash for a sub-region of an image.
§Safety
- All pointer parameters must be valid.
- The sub-region must be within the image bounds.