77 lines
2.1 KiB
Rust
77 lines
2.1 KiB
Rust
|
use super::sys;
|
||
|
|
||
|
pub struct Image {
|
||
|
pub(crate) inner: *mut sys::zbar_image_s,
|
||
|
/// Set to store the data of inner, as it will otherwise be freed when the data is dropped.
|
||
|
inner_data: Option<Vec<u8>>,
|
||
|
}
|
||
|
|
||
|
impl Image {
|
||
|
/// Link: [`sys::zbar_image_create`]
|
||
|
pub(crate) fn alloc() -> Self {
|
||
|
Self {
|
||
|
inner: unsafe { sys::zbar_image_create() },
|
||
|
inner_data: None,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// Link: [`sys::zbar_image_set_format`]
|
||
|
///
|
||
|
/// A FourCC code can be given in the format:
|
||
|
///
|
||
|
/// ```no_run
|
||
|
/// self.set_format(b"Y800")
|
||
|
/// ````
|
||
|
pub(crate) fn set_format(&mut self, fourcc: &[u8; 4]) {
|
||
|
let fourcc: u64 = fourcc[0] as u64
|
||
|
| ((fourcc[1] as u64) << 8)
|
||
|
| ((fourcc[2] as u64) << 16)
|
||
|
| ((fourcc[3] as u64) << 24);
|
||
|
unsafe { sys::zbar_image_set_format(self.inner, fourcc) }
|
||
|
}
|
||
|
|
||
|
/// Link: [`sys::zbar_image_set_size`]
|
||
|
fn set_size(&mut self, width: u32, height: u32) {
|
||
|
unsafe { sys::zbar_image_set_size(self.inner, width, height) }
|
||
|
}
|
||
|
|
||
|
/// Link: [`sys::zbar_image_set_data`]
|
||
|
///
|
||
|
/// Accepts raw data in the configured format. See: [`Image::set_format`]
|
||
|
fn set_data(&mut self, data: Vec<u8>) {
|
||
|
unsafe {
|
||
|
sys::zbar_image_set_data(
|
||
|
self.inner,
|
||
|
data.as_ptr().cast(),
|
||
|
data.len() as u64,
|
||
|
None,
|
||
|
)
|
||
|
}
|
||
|
// keep data in self to avoid use after free when data goes out of scope
|
||
|
let _ = self.inner_data.insert(data);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#[cfg(feature = "image")]
|
||
|
mod impls {
|
||
|
use super::*;
|
||
|
use image::{DynamicImage, GenericImageView};
|
||
|
|
||
|
impl From<DynamicImage> for Image {
|
||
|
fn from(value: DynamicImage) -> Self {
|
||
|
let mut image = Self::alloc();
|
||
|
let (width, height) = value.dimensions();
|
||
|
image.set_size(width, height);
|
||
|
image.set_format(b"Y800");
|
||
|
image.set_data(value.to_luma8().into_raw());
|
||
|
image
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl Drop for Image {
|
||
|
fn drop(&mut self) {
|
||
|
unsafe { sys::zbar_image_destroy(self.inner) }
|
||
|
}
|
||
|
}
|