use crate::error::DocQuadError;
use ndarray::ArrayView2;
use std::time::Instant;
pub struct DocBuffer<'a> {
pub data: &'a [u8],
pub width: u32,
pub height: u32,
pub stride: u32,
}
impl<'a> DocBuffer<'a> {
pub fn new(data: &'a [u8], width: u32, height: u32, stride: u32) -> Result<Self, DocQuadError> {
let start = Instant::now();
let required = (height as usize)
.checked_mul(stride as usize)
.ok_or(DocQuadError::InvalidBuffer)?;
if stride < width || required > data.len() {
log::error!(
"[Core::DocBuffer] - Buffer dimensions mismatch. data_len={}, required={}",
data.len(),
required
);
return Err(DocQuadError::InvalidBuffer);
}
let buffer = Self {
data,
width,
height,
stride,
};
log::debug!(
"[Core::DocBuffer] - Buffer initialized: {}x{}, stride={}. Elapsed: {}µs",
width,
height,
stride,
start.elapsed().as_micros()
);
Ok(buffer)
}
pub fn as_array_view(&self) -> Result<ArrayView2<'_, u8>, DocQuadError> {
let rows = self.height as usize;
let cols = self.width as usize;
let row_stride = self.stride as usize;
let shape = ndarray::Ix2(rows, cols);
let strides = ndarray::Ix2(row_stride, 1);
let view = unsafe {
ArrayView2::from_shape_ptr(
ndarray::ShapeBuilder::strides(shape, strides),
self.data.as_ptr(),
)
};
log::debug!(
"[Core::DocBuffer] - ArrayView2 mapped: {}x{}, row_stride={}",
cols,
rows,
row_stride
);
Ok(view)
}
}