EdgeHashGenerator

Struct EdgeHashGenerator 

Source
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

Source

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. If None, 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?
examples/version.rs (line 41)
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
Hide additional examples
examples/hash.rs (line 20)
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}
Source

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.

Source

pub fn get_error_number(&self) -> i32

Retrieves the last error number from the library.

Source

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?
examples/hash.rs (line 84)
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}
Source

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?
examples/version.rs (line 46)
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}
Source

pub fn library_version_major(&self) -> i32

Returns the major version number.

Examples found in repository?
examples/version.rs (line 47)
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}
Source

pub fn library_version_minor(&self) -> i32

Returns the minor version number.

Examples found in repository?
examples/version.rs (line 48)
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}
Source

pub fn library_version_patch(&self) -> i32

Returns the patch version number.

Examples found in repository?
examples/version.rs (line 49)
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}
Source

pub fn library_version_text(&self) -> Option<&str>

Returns the library version as a human-readable string.

Examples found in repository?
examples/version.rs (line 50)
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
Hide additional examples
examples/hash.rs (line 24)
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}
Source

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 by options.
  • hash_value: Output buffer for the computed hash. Must be at least PHOTODNA_HASH_SIZE_MAX bytes.
  • 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 of PhotoDnaOptions flags.
§Returns

0 on success, or a negative error code.

§Safety
  • image_data must point to valid pixel data of size height * stride bytes.
  • hash_value must point to a buffer of at least PHOTODNA_HASH_SIZE_MAX bytes.
Examples found in repository?
examples/hash.rs (lines 68-75)
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}
Source

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 by options.
  • hash_results: Output array for computed hashes (at least 2 entries).
  • max_hash_count: Size of the hash_results array.
  • 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 of PhotoDnaOptions flags.
§Returns

Number of hashes returned (1 or 2), or a negative error code.

§Safety
  • image_data must point to valid pixel data.
  • hash_results must point to an array of at least max_hash_count elements.
Examples found in repository?
examples/hash.rs (lines 110-118)
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}
Source

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.
Source

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.

Trait Implementations§

Source§

impl Drop for EdgeHashGenerator

Available on Windows or Linux or macOS only.
Source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.