//! ## 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 { 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) } } }