Add Gzip compression for psc and lz

This commit is contained in:
widberg 2023-11-29 18:57:40 -05:00
parent d9d9f42bec
commit 200c09f710
6 changed files with 90 additions and 21 deletions

View file

@ -4,6 +4,8 @@ use std::io::{self, BufWriter, Cursor, Read, Write};
use bff::lz::{
arcode_compress_data_with_header_writer,
arcode_decompress_data_with_header_parser,
gzip_compress_data_with_header_writer,
gzip_decompress_data_with_header_parser,
lz4_compress_data_with_header_writer,
lz4_decompress_data_with_header_parser,
lzo_compress,
@ -32,6 +34,7 @@ pub enum LzAlgorithm {
Lz4,
Arcode,
Zlib,
Gzip,
}
fn lz_internal<R: Read, W: Write>(
@ -51,6 +54,7 @@ fn lz_internal<R: Read, W: Write>(
LzAlgorithm::Lz4 => lz4_compress_data_with_header_writer(&buf, &mut writer, endian)?,
LzAlgorithm::Arcode => arcode_compress_data_with_header_writer(&buf, &mut writer, endian)?,
LzAlgorithm::Zlib => zlib_compress_data_with_header_writer(&buf, &mut writer, endian)?,
LzAlgorithm::Gzip => gzip_compress_data_with_header_writer(&buf, &mut writer, endian)?,
};
compressed.write_all(&writer.into_inner())?;
@ -114,6 +118,7 @@ fn unlz_internal<R: Read, W: Write>(
LzAlgorithm::Lz4 => lz4_decompress_data_with_header_parser(&mut reader, endian)?,
LzAlgorithm::Arcode => arcode_decompress_data_with_header_parser(&mut reader, endian)?,
LzAlgorithm::Zlib => zlib_decompress_data_with_header_parser(&mut reader, endian)?,
LzAlgorithm::Gzip => gzip_decompress_data_with_header_parser(&mut reader, endian)?,
};
uncompressed.write_all(&decompressed)?;

View file

@ -209,8 +209,16 @@ fn main() -> BffCliResult<()> {
),
Commands::RoundTrip { bigfile } => round_trip::round_trip(bigfile),
Commands::Csc { input, output, key } => csc::csc(input, output, key),
Commands::ExtractPsc { psc, directory, algorithm } => psc::extract_psc(psc, directory, algorithm),
Commands::CreatePsc { directory, psc, algorithm } => psc::create_psc(directory, psc, algorithm),
Commands::ExtractPsc {
psc,
directory,
algorithm,
} => psc::extract_psc(psc, directory, algorithm),
Commands::CreatePsc {
directory,
psc,
algorithm,
} => psc::create_psc(directory, psc, algorithm),
Commands::ExtractFatLin {
fat,
lin,

View file

@ -12,6 +12,7 @@ use crate::error::BffCliResult;
pub enum PscAlgorithm {
None,
Lz4,
Gzip,
}
impl From<PscAlgorithm> for bff::tsc::PscAlgorithm {
@ -19,15 +20,12 @@ impl From<PscAlgorithm> for bff::tsc::PscAlgorithm {
match algorithm {
PscAlgorithm::None => Self::None,
PscAlgorithm::Lz4 => Self::Lz4,
PscAlgorithm::Gzip => Self::Gzip,
}
}
}
pub fn extract_psc(
psc: &Path,
directory: &Path,
algorithm: &PscAlgorithm,
) -> BffCliResult<()> {
pub fn extract_psc(psc: &Path, directory: &Path, algorithm: &PscAlgorithm) -> BffCliResult<()> {
let mut psc_reader = BufReader::new(File::open(psc)?);
let psc = Psc::read(&mut psc_reader, (*algorithm).into())?;
@ -63,11 +61,7 @@ fn read_files_into_psc_recursively(
Ok(())
}
pub fn create_psc(
directory: &Path,
psc_path: &Path,
algorithm: &PscAlgorithm,
) -> BffCliResult<()> {
pub fn create_psc(directory: &Path, psc_path: &Path, algorithm: &PscAlgorithm) -> BffCliResult<()> {
let mut psc = Psc::default();
read_files_into_psc_recursively(&mut psc, directory, directory)?;

47
bff/src/lz/gzip.rs Normal file
View file

@ -0,0 +1,47 @@
use std::io::{Read, Seek, Write};
use binrw::{BinResult, Endian};
use flate2::read::MultiGzDecoder;
use flate2::write::GzEncoder;
use flate2::Compression;
use crate::BffResult;
#[binrw::writer(writer)]
pub fn gzip_compress_data_with_header_writer_internal(data: &[u8]) -> BinResult<()> {
let mut gz = GzEncoder::new(writer, Compression::fast());
gz.write_all(data)?;
Ok(())
}
pub fn gzip_compress_data_with_header_writer<W: Write + Seek>(
data: &[u8],
writer: &mut W,
endian: Endian,
) -> BffResult<()> {
Ok(gzip_compress_data_with_header_writer_internal(
data,
writer,
endian,
(),
)?)
}
#[binrw::parser(reader)]
pub fn gzip_decompress_data_with_header_parser_internal() -> BinResult<Vec<u8>> {
let mut gz = MultiGzDecoder::new(reader);
let mut buf = Vec::new();
gz.read_to_end(&mut buf)?;
Ok(buf)
}
pub fn gzip_decompress_data_with_header_parser<R: Read + Seek>(
reader: &mut R,
endian: Endian,
) -> BffResult<Vec<u8>> {
Ok(gzip_decompress_data_with_header_parser_internal(
reader,
endian,
(),
)?)
}

View file

@ -1,10 +1,12 @@
mod arcode;
mod gzip;
mod lz4;
mod lzo;
mod lzrs;
mod zlib;
pub use arcode::*;
pub use gzip::*;
pub use lz4::*;
pub use lzo::*;
pub use lzrs::*;

View file

@ -8,6 +8,8 @@ use itertools::Itertools;
use crate::helpers::StringUntilNull;
use crate::lz::{
gzip_compress_data_with_header_writer_internal,
gzip_decompress_data_with_header_parser_internal,
lz4_compress_data_with_header_writer_internal,
lz4_decompress_data_with_header_parser_internal,
};
@ -43,10 +45,6 @@ impl BinRead for Psc {
while reader.stream_position()? != end {
let path_string = StringUntilNull::read(reader)?.0;
let path = PathBuf::from(path_string);
let cr = u8::read_le(reader)?;
assert_eq!(cr, 0x0D);
let lf = u8::read_le(reader)?;
assert_eq!(lf, 0x0A);
let data = StringUntilNull::read(reader)?.0;
psc.tscs.insert(path, data);
}
@ -73,7 +71,7 @@ impl BinWrite for Psc {
.join("\\")
.as_bytes(),
)?;
writer.write_all(&[0x00, 0x0D, 0x0A])?;
writer.write_all(&[0x00])?;
writer.write_all(data.as_bytes())?;
writer.write_all(&[0x00])?;
}
@ -86,13 +84,11 @@ impl BinWrite for Psc {
pub enum PscAlgorithm {
None,
Lz4,
Gzip,
}
impl Psc {
pub fn read<R: Read + Seek>(
reader: &mut R,
psc_compression: PscAlgorithm,
) -> BffResult<Self> {
pub fn read<R: Read + Seek>(reader: &mut R, psc_compression: PscAlgorithm) -> BffResult<Self> {
match psc_compression {
PscAlgorithm::None => Ok(<Self as BinRead>::read(reader)?),
PscAlgorithm::Lz4 => {
@ -102,6 +98,15 @@ impl Psc {
(),
)?);
Ok(<Self as BinRead>::read(&mut psc_data)?)
}
PscAlgorithm::Gzip => {
let mut psc_data = Cursor::new(gzip_decompress_data_with_header_parser_internal(
reader,
Endian::Little,
(),
)?);
Ok(<Self as BinRead>::read(&mut psc_data)?)
}
}
@ -127,6 +132,14 @@ impl Psc {
(),
)?;
}
PscAlgorithm::Gzip => {
gzip_compress_data_with_header_writer_internal(
&psc_data.into_inner(),
writer,
Endian::Little,
(),
)?;
}
}
Ok(())