use alloc::borrow::Cow;
use alloc::boxed::Box;
use crate::format::ImageFormat;
use crate::orientation::OrientationHint;
use crate::{DecodeCapabilities, ImageInfo, OutputInfo, ResourceLimits, StopToken};
use zenpixels::PixelDescriptor;
use super::BoxedError;
use super::decoder::{AnimationFrameDecoder, Decode, StreamingDecode};
use super::dyn_decoding::{
AnimationFrameDecoderShim, DecoderShim, DynAnimationFrameDecoder, DynDecoder,
DynStreamingDecoder, StreamingDecoderShim,
};
pub trait DecoderConfig: Clone + Send + Sync {
type Error: core::error::Error + Send + Sync + 'static;
type Job<'a>: DecodeJob<'a, Error = Self::Error> + 'static;
fn formats() -> &'static [ImageFormat];
fn supported_descriptors() -> &'static [PixelDescriptor];
fn capabilities() -> &'static DecodeCapabilities {
&DecodeCapabilities::EMPTY
}
fn job<'a>(self) -> Self::Job<'a>;
}
pub trait DecodeJob<'a>: Sized {
type Error: core::error::Error + Send + Sync + 'static;
type Dec: Decode<Error = Self::Error>;
type StreamDec: StreamingDecode<Error = Self::Error> + Send;
type AnimationFrameDec: AnimationFrameDecoder<Error = Self::Error> + Send + 'static;
fn with_stop(self, stop: StopToken) -> Self;
fn with_limits(self, limits: ResourceLimits) -> Self;
fn with_policy(self, _policy: crate::DecodePolicy) -> Self {
self
}
fn probe(&self, data: &[u8]) -> Result<ImageInfo, Self::Error>;
fn probe_full(&self, data: &[u8]) -> Result<ImageInfo, Self::Error> {
self.probe(data)
}
fn with_crop_hint(self, _x: u32, _y: u32, _width: u32, _height: u32) -> Self {
self
}
fn with_orientation(self, _hint: OrientationHint) -> Self {
self
}
fn with_start_frame_index(self, _index: u32) -> Self {
self
}
fn with_extract_gain_map(self, _extract: bool) -> Self {
self
}
fn extensions(&self) -> Option<&dyn core::any::Any> {
None
}
fn extensions_mut(&mut self) -> Option<&mut dyn core::any::Any> {
None
}
fn output_info(&self, data: &[u8]) -> Result<OutputInfo, Self::Error>;
fn decoder(
self,
data: Cow<'a, [u8]>,
preferred: &[PixelDescriptor],
) -> Result<Self::Dec, Self::Error>;
fn push_decoder(
self,
data: Cow<'a, [u8]>,
sink: &mut dyn crate::DecodeRowSink,
preferred: &[PixelDescriptor],
) -> Result<OutputInfo, Self::Error>;
fn streaming_decoder(
self,
data: Cow<'a, [u8]>,
preferred: &[PixelDescriptor],
) -> Result<Self::StreamDec, Self::Error>;
fn animation_frame_decoder(
self,
data: Cow<'a, [u8]>,
preferred: &[PixelDescriptor],
) -> Result<Self::AnimationFrameDec, Self::Error>;
fn dyn_decoder(
self,
data: Cow<'a, [u8]>,
preferred: &[PixelDescriptor],
) -> Result<Box<dyn DynDecoder + 'a>, BoxedError>
where
Self: 'a,
{
let dec = self
.decoder(data, preferred)
.map_err(|e| Box::new(e) as BoxedError)?;
Ok(Box::new(DecoderShim(dec)))
}
fn dyn_animation_frame_decoder(
self,
data: Cow<'a, [u8]>,
preferred: &[PixelDescriptor],
) -> Result<Box<dyn DynAnimationFrameDecoder>, BoxedError>
where
Self: 'a,
Self::AnimationFrameDec: Send,
{
let dec = self
.animation_frame_decoder(data, preferred)
.map_err(|e| Box::new(e) as BoxedError)?;
Ok(Box::new(AnimationFrameDecoderShim(dec)))
}
fn dyn_streaming_decoder(
self,
data: Cow<'a, [u8]>,
preferred: &[PixelDescriptor],
) -> Result<Box<dyn DynStreamingDecoder + 'a>, BoxedError>
where
Self: 'a,
Self::StreamDec: Send,
{
let dec = self
.streaming_decoder(data, preferred)
.map_err(|e| Box::new(e) as BoxedError)?;
Ok(Box::new(StreamingDecoderShim(dec)))
}
}