mirror of
https://github.com/widberg/bff
synced 2026-08-23 14:26:03 -04:00
Add Gzip compression for psc and lz
This commit is contained in:
parent
d9d9f42bec
commit
200c09f710
6 changed files with 90 additions and 21 deletions
|
|
@ -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)?;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
47
bff/src/lz/gzip.rs
Normal 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,
|
||||
(),
|
||||
)?)
|
||||
}
|
||||
|
|
@ -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::*;
|
||||
|
|
|
|||
|
|
@ -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(())
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue