use crate::EncodeOutput;
use enough::Stop;
use zenpixels::{PixelDescriptor, PixelSlice, PixelSliceMut};
pub trait Encoder: Sized {
type Error: core::error::Error + Send + Sync + 'static;
fn reject(op: crate::UnsupportedOperation) -> Self::Error;
fn preferred_strip_height(&self) -> u32 {
0
}
fn encode(self, pixels: PixelSlice<'_>) -> Result<EncodeOutput, Self::Error>;
fn encode_srgba8(
self,
data: &mut [u8],
make_opaque: bool,
width: u32,
height: u32,
stride_pixels: u32,
) -> Result<EncodeOutput, Self::Error> {
use zenpixels::AlphaMode;
let descriptor = if make_opaque {
PixelDescriptor::RGBA8_SRGB.with_alpha(Some(AlphaMode::Undefined))
} else {
PixelDescriptor::RGBA8_SRGB
};
let stride_bytes = stride_pixels as usize * 4;
let pixels = PixelSlice::new(data, width, height, stride_bytes, descriptor).expect(
"encode_srgba8: data.len() does not match width * height * 4 (stride-adjusted)",
);
self.encode(pixels)
}
fn push_rows(&mut self, _rows: PixelSlice<'_>) -> Result<(), Self::Error> {
Err(Self::reject(crate::UnsupportedOperation::RowLevelEncode))
}
fn finish(self) -> Result<EncodeOutput, Self::Error> {
Err(Self::reject(crate::UnsupportedOperation::RowLevelEncode))
}
fn encode_from(
self,
_source: &mut dyn FnMut(u32, PixelSliceMut<'_>) -> usize,
) -> Result<EncodeOutput, Self::Error> {
Err(Self::reject(crate::UnsupportedOperation::PullEncode))
}
}
pub trait AnimationFrameEncoder: Sized {
type Error: core::error::Error + Send + Sync + 'static;
fn reject(op: crate::UnsupportedOperation) -> Self::Error;
fn push_frame(
&mut self,
pixels: PixelSlice<'_>,
duration_ms: u32,
stop: Option<&dyn Stop>,
) -> Result<(), Self::Error>;
fn finish(self, stop: Option<&dyn Stop>) -> Result<EncodeOutput, Self::Error>;
}
impl AnimationFrameEncoder for () {
type Error = crate::UnsupportedOperation;
fn reject(op: crate::UnsupportedOperation) -> Self::Error {
op
}
fn push_frame(
&mut self,
_: PixelSlice<'_>,
_: u32,
_: Option<&dyn Stop>,
) -> Result<(), Self::Error> {
Err(crate::UnsupportedOperation::AnimationEncode)
}
fn finish(self, _: Option<&dyn Stop>) -> Result<EncodeOutput, Self::Error> {
Err(crate::UnsupportedOperation::AnimationEncode)
}
}