use crate::{
memory::{LeptonicaDestroy, RefCounted, RefCountedExclusive},
Pix,
};
use leptonica_sys::{
pixaDestroy, pixaGetCount, pixaGetPix, pixaReadMultipageTiff, L_CLONE, L_COPY,
};
use std::{convert::TryInto, ffi::CStr};
#[derive(Debug, PartialEq)]
pub struct Pixa(*mut leptonica_sys::Pixa);
impl AsRef<leptonica_sys::Pixa> for Pixa {
fn as_ref(&self) -> &leptonica_sys::Pixa {
unsafe { &*self.0 }
}
}
impl AsMut<leptonica_sys::Pixa> for Pixa {
fn as_mut(&mut self) -> &mut leptonica_sys::Pixa {
unsafe { &mut *self.0 }
}
}
impl Pixa {
pub unsafe fn new_from_pointer(p: *mut leptonica_sys::Pixa) -> Self {
Self(p)
}
pub fn read_multipage_tiff(filename: &CStr) -> Option<RefCountedExclusive<Self>> {
let ptr = unsafe { pixaReadMultipageTiff(filename.as_ptr()) };
if ptr.is_null() {
None
} else {
Some(unsafe { RefCountedExclusive::new(Self(ptr)) })
}
}
pub fn get_count(&self) -> leptonica_sys::l_int32 {
unsafe { pixaGetCount(self.0) }
}
pub fn get_pix_copied(
&self,
index: leptonica_sys::l_int32,
) -> Option<RefCountedExclusive<Pix>> {
unsafe {
pixaGetPix(self.0, index, L_COPY.try_into().unwrap())
.as_mut()
.map(|raw| RefCountedExclusive::new(Pix::new_from_pointer(raw)))
}
}
pub fn get_pix_cloned(&self, index: leptonica_sys::l_int32) -> Option<RefCounted<Pix>> {
unsafe {
pixaGetPix(self.0, index, L_CLONE.try_into().unwrap())
.as_mut()
.map(|raw| RefCounted::new(Pix::new_from_pointer(raw)))
}
}
}
impl LeptonicaDestroy for Pixa {
unsafe fn destroy(&mut self) {
pixaDestroy(&mut self.0);
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn read_multipage_tiff_test() {
let pixa =
Pixa::read_multipage_tiff(CStr::from_bytes_with_nul(b"multipage.tiff\0").unwrap())
.unwrap();
assert_eq!(pixa.get_count(), 2);
assert_eq!(pixa.get_pix_copied(0).unwrap().get_width(), 165);
assert_eq!(pixa.get_pix_cloned(0).unwrap().get_height(), 67);
assert_eq!(pixa.get_pix_copied(1).unwrap().get_width(), 165);
assert_eq!(pixa.get_pix_cloned(1).unwrap().get_height(), 67);
assert!(pixa.get_pix_copied(2).is_none());
assert!(pixa.get_pix_cloned(2).is_none());
}
}