mirror of
https://github.com/redstrate/Physis.git
synced 2025-04-21 20:27:46 +00:00
Switch to texture2ddecoder
This crate supports more BCn decoders which texpresso doesn't (like BC7.)
This commit is contained in:
parent
1b055b3f7a
commit
3e00c35bd8
2 changed files with 29 additions and 32 deletions
|
@ -44,7 +44,7 @@ game_install = []
|
||||||
# enables support for extracting visual data, such as models, textures, materials, etc.
|
# enables support for extracting visual data, such as models, textures, materials, etc.
|
||||||
# this enables a bunch of dependencies!
|
# this enables a bunch of dependencies!
|
||||||
# tip: can be safely turned off for launchers and other tools that simply need to extract the bare minimum of data
|
# tip: can be safely turned off for launchers and other tools that simply need to extract the bare minimum of data
|
||||||
visual_data = ["dep:half", "dep:bitflags", "dep:texpresso"]
|
visual_data = ["dep:half", "dep:bitflags", "dep:texture2ddecoder"]
|
||||||
|
|
||||||
# testing only features
|
# testing only features
|
||||||
retail_game_testing = []
|
retail_game_testing = []
|
||||||
|
@ -70,4 +70,4 @@ half = { version = "2", optional = true }
|
||||||
bitflags = { version = "1.3", optional = true }
|
bitflags = { version = "1.3", optional = true }
|
||||||
|
|
||||||
# needed for dxt/bc decompression
|
# needed for dxt/bc decompression
|
||||||
texpresso = { version = "2", optional = true }
|
texture2ddecoder = { version = "0.0.5", optional = true }
|
57
src/tex.rs
57
src/tex.rs
|
@ -8,7 +8,7 @@ use std::io::{Cursor, Read, Seek, SeekFrom};
|
||||||
use binrw::BinRead;
|
use binrw::BinRead;
|
||||||
use binrw::binrw;
|
use binrw::binrw;
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
use texpresso::Format;
|
use texture2ddecoder::{decode_bc1, decode_bc3, decode_bc5};
|
||||||
use crate::ByteSpan;
|
use crate::ByteSpan;
|
||||||
|
|
||||||
// Attributes and Format are adapted from Lumina (https://github.com/NotAdam/Lumina/blob/master/src/Lumina/Data/Files/TexFile.cs)
|
// Attributes and Format are adapted from Lumina (https://github.com/NotAdam/Lumina/blob/master/src/Lumina/Data/Files/TexFile.cs)
|
||||||
|
@ -79,6 +79,8 @@ pub struct Texture {
|
||||||
pub rgba: Vec<u8>,
|
pub rgba: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DecodeFunction = fn(&[u8], usize, usize, &mut [u32]) -> Result<(), &'static str>;
|
||||||
|
|
||||||
impl Texture {
|
impl Texture {
|
||||||
/// Reads an existing TEX file
|
/// Reads an existing TEX file
|
||||||
pub fn from_existing(buffer: ByteSpan) -> Option<Texture> {
|
pub fn from_existing(buffer: ByteSpan) -> Option<Texture> {
|
||||||
|
@ -92,7 +94,7 @@ impl Texture {
|
||||||
let mut src = vec![0u8; buffer.len() - std::mem::size_of::<TexHeader>()];
|
let mut src = vec![0u8; buffer.len() - std::mem::size_of::<TexHeader>()];
|
||||||
cursor.read_exact(src.as_mut_slice()).ok()?;
|
cursor.read_exact(src.as_mut_slice()).ok()?;
|
||||||
|
|
||||||
let mut dst;
|
let mut dst : Vec<u8>;
|
||||||
|
|
||||||
match header.format {
|
match header.format {
|
||||||
TextureFormat::B4G4R4A4 => {
|
TextureFormat::B4G4R4A4 => {
|
||||||
|
@ -119,40 +121,16 @@ impl Texture {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TextureFormat::B8G8R8A8 => {
|
TextureFormat::B8G8R8A8 => {
|
||||||
dst = src;
|
dst = src; // TODO: not correct, of course
|
||||||
}
|
}
|
||||||
TextureFormat::BC1 => {
|
TextureFormat::BC1 => {
|
||||||
dst = vec![0u8; header.width as usize * header.height as usize * 4];
|
dst = Texture::decode(&src, header.width as usize, header.height as usize, decode_bc1);
|
||||||
|
|
||||||
let format = Format::Bc1;
|
|
||||||
format.decompress(
|
|
||||||
&src,
|
|
||||||
header.width as usize,
|
|
||||||
header.height as usize,
|
|
||||||
dst.as_mut_slice(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
TextureFormat::BC3 => {
|
TextureFormat::BC3 => {
|
||||||
dst = vec![0u8; header.width as usize * header.height as usize * 4];
|
dst = Texture::decode(&src, header.width as usize, header.height as usize, decode_bc3);
|
||||||
|
|
||||||
let format = Format::Bc3;
|
|
||||||
format.decompress(
|
|
||||||
&src,
|
|
||||||
header.width as usize,
|
|
||||||
header.height as usize,
|
|
||||||
dst.as_mut_slice(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
TextureFormat::BC5 => {
|
TextureFormat::BC5 => {
|
||||||
dst = vec![0u8; header.width as usize * header.height as usize * 4];
|
dst = Texture::decode(&src, header.width as usize, header.height as usize, decode_bc5);
|
||||||
|
|
||||||
let format = Format::Bc5;
|
|
||||||
format.decompress(
|
|
||||||
&src,
|
|
||||||
header.width as usize,
|
|
||||||
header.height as usize,
|
|
||||||
dst.as_mut_slice(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,6 +140,25 @@ impl Texture {
|
||||||
rgba: dst,
|
rgba: dst,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn decode(src: &[u8], width: usize, height: usize, decode_func: DecodeFunction) -> Vec<u8> {
|
||||||
|
let mut image: Vec<u32> = vec![0; (width * height) as usize];
|
||||||
|
decode_func(
|
||||||
|
&src,
|
||||||
|
width as usize,
|
||||||
|
height as usize,
|
||||||
|
&mut image,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
image
|
||||||
|
.iter()
|
||||||
|
.flat_map(|x| {
|
||||||
|
let v = x.to_le_bytes();
|
||||||
|
[v[2], v[1], v[0], v[3]]
|
||||||
|
})
|
||||||
|
.collect::<Vec<u8>>()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
Loading…
Add table
Reference in a new issue