pub mod dds;
pub mod ktx2;
use crate::alpha::AlphaMode;
use crate::error::Result;
use crate::surface::{ColorSpace, Image};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum InputFormat {
Ktx2,
Dds,
}
pub fn detect_container(data: &[u8]) -> Option<InputFormat> {
if data.starts_with(&::ktx2::MAGIC) {
return Some(InputFormat::Ktx2);
}
if data.len() >= 4 && data[..4] == [0x44, 0x44, 0x53, 0x20] {
return Some(InputFormat::Dds);
}
None
}
#[derive(Debug, Clone, Copy, Default)]
pub struct InputOverrides {
pub color_space: Option<ColorSpace>,
pub alpha: Option<AlphaMode>,
}
pub fn decode_container(data: &[u8], overrides: InputOverrides) -> Result<Option<Image>> {
match detect_container(data) {
Some(format) => decode_container_as(data, format, overrides).map(Some),
None => Ok(None),
}
}
pub fn decode_container_as(
data: &[u8],
format: InputFormat,
overrides: InputOverrides,
) -> Result<Image> {
let mut image = match format {
InputFormat::Ktx2 => ktx2::decode_ktx2_image(data)?,
InputFormat::Dds => dds::decode_dds_image(data)?,
};
if overrides.color_space.is_some() || overrides.alpha.is_some() {
for layer in &mut image.surfaces {
for surface in layer {
if let Some(cs) = overrides.color_space {
surface.color_space = cs;
}
if let Some(alpha) = overrides.alpha {
surface.alpha = alpha;
}
}
}
}
Ok(image)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn detect_ktx2_magic() {
let mut data = vec![0u8; 80];
data[..12].copy_from_slice(&::ktx2::MAGIC);
assert_eq!(detect_container(&data), Some(InputFormat::Ktx2));
}
#[test]
fn detect_dds_magic() {
let data = [0x44, 0x44, 0x53, 0x20, 0, 0, 0, 0];
assert_eq!(detect_container(&data), Some(InputFormat::Dds));
}
#[test]
fn detect_unknown_returns_none() {
let data = [0x89, 0x50, 0x4E, 0x47]; assert_eq!(detect_container(&data), None);
}
#[test]
fn detect_empty_returns_none() {
assert_eq!(detect_container(&[]), None);
}
}