use std::io::{BufRead, Seek, SeekFrom};
use crate::{
util::{read_u32, Endian},
ImageResult, ImageSize,
};
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum DdsCompression {
Bc1,
Bc2,
Bc3,
Bc4,
Bc5,
Bc6h,
Bc7,
Rgba32,
Rgb24,
Unknown,
}
pub fn size<R: BufRead + Seek>(reader: &mut R) -> ImageResult<ImageSize> {
reader.seek(SeekFrom::Start(12))?;
let height = read_u32(reader, &Endian::Little)? as usize;
let width = read_u32(reader, &Endian::Little)? as usize;
Ok(ImageSize { width, height })
}
pub fn matches(header: &[u8]) -> bool {
header.starts_with(b"DDS ")
}
pub fn detect_compression<R: BufRead + Seek>(reader: &mut R) -> ImageResult<DdsCompression> {
reader.seek(SeekFrom::Start(84))?; let mut fourcc = [0u8; 4];
reader.read_exact(&mut fourcc)?;
let compression = match &fourcc {
b"DXT1" => DdsCompression::Bc1,
b"DXT3" => DdsCompression::Bc2,
b"DXT5" => DdsCompression::Bc3,
b"ATI1" | b"BC4U" | b"BC4S" => DdsCompression::Bc4,
b"ATI2" | b"BC5U" | b"BC5S" => DdsCompression::Bc5,
b"BC6H" => DdsCompression::Bc6h,
b"BC7U" | b"BC7L" => DdsCompression::Bc7,
b"DX10" => {
reader.seek(SeekFrom::Start(128))?; let dxgi_format = read_u32(reader, &Endian::Little)?;
match dxgi_format {
95 => DdsCompression::Bc6h, 96 => DdsCompression::Bc6h, 98 => DdsCompression::Bc7, 99 => DdsCompression::Bc7, _ => DdsCompression::Unknown,
}
}
[0, 0, 0, 0] => {
let rgb_bit_count = read_u32(reader, &Endian::Little)?;
match rgb_bit_count {
32 => DdsCompression::Rgba32,
24 => DdsCompression::Rgb24,
_ => DdsCompression::Unknown,
}
}
_ => DdsCompression::Unknown,
};
Ok(compression)
}