keyfork/crates/qrcode/keyfork-zbar/src/image_scanner.rs

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) }
}
}