use std::convert::TryFrom;
use std::slice;
use mupdf_sys::*;
use crate::{context, Error, Pixmap};
#[derive(Debug)]
pub struct Bitmap {
pub(crate) inner: *mut fz_bitmap,
}
impl Bitmap {
pub fn from_pixmap(pixmap: &Pixmap) -> Result<Self, Error> {
unsafe { ffi_try!(mupdf_new_bitmap_from_pixmap(context(), pixmap.inner)) }
.map(|inner| Self { inner })
}
pub fn width(&self) -> u32 {
unsafe { (*self.inner).w as u32 }
}
pub fn height(&self) -> u32 {
unsafe { (*self.inner).h as u32 }
}
pub fn stride(&self) -> i32 {
unsafe { (*self.inner).stride }
}
pub fn n(&self) -> i32 {
unsafe { (*self.inner).n }
}
pub fn resolution(&self) -> (i32, i32) {
unsafe {
let x_res = (*self.inner).xres;
let y_res = (*self.inner).yres;
(x_res, y_res)
}
}
pub fn samples(&self) -> &[u8] {
let len = (self.width() * self.height()) as usize;
unsafe { slice::from_raw_parts((*self.inner).samples, len) }
}
pub fn samples_mut(&mut self) -> &mut [u8] {
let len = (self.width() * self.height()) as usize;
unsafe { slice::from_raw_parts_mut((*self.inner).samples, len) }
}
}
impl Drop for Bitmap {
fn drop(&mut self) {
if !self.inner.is_null() {
unsafe {
fz_drop_bitmap(context(), self.inner);
}
}
}
}
impl TryFrom<Pixmap> for Bitmap {
type Error = Error;
fn try_from(pixmap: Pixmap) -> Result<Self, Self::Error> {
Self::from_pixmap(&pixmap)
}
}
#[cfg(test)]
mod test {
use crate::{Bitmap, Colorspace, Pixmap};
#[test]
fn test_new_bitmap() {
let cs = Colorspace::device_gray();
let mut pixmap = Pixmap::new_with_w_h(&cs, 100, 100, false).expect("Pixmap::new_with_w_h");
pixmap.clear().unwrap();
let bitmap = Bitmap::from_pixmap(&pixmap).unwrap();
assert_eq!(bitmap.width(), 100);
assert_eq!(bitmap.n(), 1);
}
#[test]
fn test_new_bitmap_error() {
let cs = Colorspace::device_rgb();
let mut pixmap = Pixmap::new_with_w_h(&cs, 100, 100, false).expect("Pixmap::new_with_w_h");
pixmap.clear().unwrap();
assert!(Bitmap::from_pixmap(&pixmap).is_err());
}
}