use std::any::Any;
use crate::error::Result;
pub(crate) use crate::quality::Quality;
use crate::surface::Surface;
pub trait EncoderSettings: Any + Send + Sync {
fn as_any(&self) -> &dyn Any;
}
pub trait Encoder: Send + Sync {
fn name(&self) -> &str;
fn supported_formats(&self) -> &[ktx2::Format];
fn required_input_format(&self, format: ktx2::Format) -> ktx2::Format;
fn compress(
&self,
surface: &Surface,
format: ktx2::Format,
quality: Quality,
settings: Option<&dyn EncoderSettings>,
) -> Result<Vec<u8>>;
}
pub struct EncoderRegistry {
encoders: Vec<Box<dyn Encoder>>,
}
impl EncoderRegistry {
pub fn new() -> Self {
Self {
encoders: Vec::new(),
}
}
pub fn default_registry() -> Self {
#[allow(unused_mut)]
let mut r = Self::new();
#[cfg(feature = "encoder-bc7enc")]
r.register(Box::new(self::bc7enc::Bc7encEncoder));
#[cfg(feature = "encoder-intel")]
r.register(Box::new(self::ispc::IspcEncoder));
#[cfg(feature = "encoder-etcpak")]
r.register(Box::new(self::etcpak::EtcpakEncoder));
#[cfg(feature = "encoder-amd")]
r.register(Box::new(self::compressonator::CompressonatorEncoder));
#[cfg(feature = "encoder-astcenc")]
r.register(Box::new(self::astcenc::AstcencEncoder));
r
}
pub fn register(&mut self, encoder: Box<dyn Encoder>) {
self.encoders.push(encoder);
}
pub fn find(&self, format: ktx2::Format) -> Option<&dyn Encoder> {
self.encoders
.iter()
.find(|e| e.supported_formats().contains(&format))
.map(|e| e.as_ref())
}
pub fn find_by_name(&self, name: &str, format: ktx2::Format) -> Option<&dyn Encoder> {
self.encoders
.iter()
.find(|e| e.name() == name && e.supported_formats().contains(&format))
.map(|e| e.as_ref())
}
pub fn encoders(&self) -> &[Box<dyn Encoder>] {
&self.encoders
}
pub fn available_formats(&self) -> Vec<String> {
let mut formats = Vec::new();
for encoder in &self.encoders {
for &fmt in encoder.supported_formats() {
formats.push(format!("{}_{:?}", encoder.name(), fmt).to_lowercase());
}
}
formats
}
}
impl Default for EncoderRegistry {
fn default() -> Self {
Self::new()
}
}
#[cfg(any(
feature = "encoder-intel",
feature = "encoder-etcpak",
feature = "encoder-amd",
))]
mod edge;
#[cfg(feature = "encoder-intel")]
pub mod ispc;
#[cfg(feature = "encoder-bc7enc")]
pub mod bc7enc;
#[cfg(feature = "encoder-etcpak")]
pub mod etcpak;
#[cfg(feature = "encoder-astcenc")]
pub mod astcenc;
#[cfg(feature = "encoder-amd")]
pub mod compressonator;