use crate::common::error::Result;
use crate::common::types::{FrameHeader, PixelFormat, ScalingFactor};
use crate::decode::pipeline::{Decoder, Image};
pub struct StreamingDecoder<'a> {
inner: Decoder<'a>,
}
impl<'a> StreamingDecoder<'a> {
pub fn new(data: &'a [u8]) -> Result<Self> {
let inner = Decoder::new(data)?;
Ok(Self { inner })
}
pub fn header(&self) -> &FrameHeader {
self.inner.header()
}
pub fn set_output_format(&mut self, format: PixelFormat) {
self.inner.set_output_format(format);
}
pub fn set_scale(&mut self, scale: ScalingFactor) {
self.inner.set_scale(scale);
}
pub fn set_lenient(&mut self, lenient: bool) {
self.inner.set_lenient(lenient);
}
pub fn crop_scanline(&mut self, xoffset: &mut usize, width: &mut usize) -> Result<()> {
let header = self.inner.header();
let max_h = header
.components
.iter()
.map(|c| c.horizontal_sampling as usize)
.max()
.unwrap_or(1);
let block_size: usize = 8;
let imcu_width = max_h * block_size;
let aligned_x = (*xoffset / imcu_width) * imcu_width;
let aligned_end = (*xoffset + *width).div_ceil(imcu_width) * imcu_width;
let aligned_width = (aligned_end - aligned_x).min(header.width as usize - aligned_x);
*xoffset = aligned_x;
*width = aligned_width;
self.inner.set_crop(aligned_x, aligned_width);
Ok(())
}
pub fn skip_scanlines(&mut self, num_lines: usize) -> Result<usize> {
Ok(num_lines)
}
pub fn decode(&self) -> Result<Image> {
self.inner.decode_image()
}
}