94 lines
2.5 KiB
Rust
94 lines
2.5 KiB
Rust
//! ## Image scanning
|
|
|
|
use super::{
|
|
image::Image,
|
|
symbol::{Symbol, SymbolType},
|
|
sys, Config,
|
|
};
|
|
|
|
/// Errors encountered while creating or using an [`ImageScanner`].
|
|
#[derive(thiserror::Error, Debug)]
|
|
pub enum ImageScannerError {
|
|
/// The provided configuration resulted in an error.
|
|
#[error("Unable to set Image Scanner configuration")]
|
|
UnableToSetConfig,
|
|
}
|
|
|
|
/// An [`ImageScanner`].
|
|
///
|
|
/// Link: [`sys::zbar_image_scanner_t`]
|
|
pub struct ImageScanner {
|
|
inner: *mut sys::zbar_image_scanner_t,
|
|
}
|
|
|
|
impl ImageScanner {
|
|
/// create a new ImageScanner.
|
|
///
|
|
/// Link: [`sys::zbar_image_scanner_create`]
|
|
pub fn new() -> Self {
|
|
Self {
|
|
inner: unsafe { sys::zbar_image_scanner_create() },
|
|
}
|
|
}
|
|
|
|
/// Set a configuration option for the ImageScanner.
|
|
///
|
|
/// Link: [`sys::zbar_image_scanner_set_config`]
|
|
///
|
|
/// # Errors
|
|
/// The function may error if the provided configuration was invalid.
|
|
pub fn set_config(
|
|
&mut self,
|
|
symbol: SymbolType,
|
|
config: Config,
|
|
value: i32,
|
|
) -> Result<(), ImageScannerError> {
|
|
let result =
|
|
unsafe { sys::zbar_image_scanner_set_config(self.inner, symbol, config, value) };
|
|
|
|
if result != 0 {
|
|
return Err(ImageScannerError::UnableToSetConfig);
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Scan an [`Image`] for QR codes.
|
|
///
|
|
/// Link: [`sys::zbar_scan_image`]
|
|
///
|
|
/// TODO: return an iterator over scanned values
|
|
pub fn scan_image(
|
|
&mut self,
|
|
image: &Image,
|
|
) -> Vec<Symbol> {
|
|
unsafe { sys::zbar_scan_image(self.inner, image.inner) };
|
|
let mut result = vec![];
|
|
let mut symbol = unsafe { sys::zbar_image_first_symbol(image.inner) };
|
|
while !symbol.is_null() {
|
|
let symbol_type = unsafe { sys::zbar_symbol_get_type(symbol) };
|
|
let symbol_data = unsafe { sys::zbar_symbol_get_data(symbol) };
|
|
let symbol_data_len = unsafe { sys::zbar_symbol_get_data_length(symbol) };
|
|
let symbol_slice = unsafe {
|
|
std::slice::from_raw_parts(symbol_data as *const u8, symbol_data_len as usize)
|
|
};
|
|
result.push(Symbol::new(symbol_type, symbol_slice));
|
|
symbol = unsafe { sys::zbar_symbol_next(symbol) };
|
|
}
|
|
|
|
result
|
|
}
|
|
}
|
|
|
|
impl Default for ImageScanner {
|
|
fn default() -> Self {
|
|
Self::new()
|
|
}
|
|
}
|
|
|
|
impl Drop for ImageScanner {
|
|
fn drop(&mut self) {
|
|
unsafe { sys::zbar_image_scanner_destroy(self.inner) }
|
|
}
|
|
}
|