use byteorder::{BigEndian, ReadBytesExt};
use nalgebra::{DMatrix, Scalar};
use png::{self, HasParameters};
use std::{self, fs::File, io::Cursor, path::Path};
pub fn read_png_16bits<P: AsRef<Path>>(
file_path: P,
) -> Result<(usize, usize, Vec<u16>), png::DecodingError> {
let img_file = File::open(file_path)?;
let mut decoder = png::Decoder::new(img_file);
decoder.set(png::Transformations::IDENTITY);
let (info, mut reader) = decoder.read_info()?;
let mut buffer = vec![0; info.buffer_size()];
reader.next_frame(&mut buffer)?;
let mut buffer_u16 = vec![0; (info.width * info.height) as usize];
let mut buffer_cursor = Cursor::new(buffer);
buffer_cursor.read_u16_into::<BigEndian>(&mut buffer_u16)?;
Ok((info.width as usize, info.height as usize, buffer_u16))
}
pub fn zip_mask_map<T, U, F>(mat: &DMatrix<T>, mask: &DMatrix<bool>, default: U, f: F) -> DMatrix<U>
where
T: Scalar,
U: Scalar,
F: Fn(T) -> U,
{
mat.zip_map(mask, |x, is_true| if is_true { f(x) } else { default })
}
pub fn div_rem<T>(x: T, y: T) -> (T, T)
where
T: std::ops::Div<Output = T> + std::ops::Rem<Output = T> + Copy,
{
(x / y, x % y)
}