mirror of
https://github.com/lifegpc/msg-tool.git
synced 2026-06-14 00:44:26 +08:00
Allow custom min len header
This commit is contained in:
@@ -61,6 +61,7 @@ impl ScriptBuilder for ArtemisAsbBuilder {
|
||||
writer: Box<dyn WriteSeek + 'a>,
|
||||
encoding: Encoding,
|
||||
file_encoding: Encoding,
|
||||
_config: &ExtraConfig,
|
||||
) -> Result<()> {
|
||||
create_file(filename, writer, encoding, file_encoding)
|
||||
}
|
||||
|
||||
@@ -94,6 +94,7 @@ pub trait ScriptBuilder: std::fmt::Debug {
|
||||
_writer: Box<dyn WriteSeek + 'a>,
|
||||
_encoding: Encoding,
|
||||
_file_encoding: Encoding,
|
||||
_config: &ExtraConfig,
|
||||
) -> Result<()> {
|
||||
Err(anyhow::anyhow!(
|
||||
"This script type does not support creating directly."
|
||||
@@ -106,10 +107,11 @@ pub trait ScriptBuilder: std::fmt::Debug {
|
||||
output_filename: &str,
|
||||
encoding: Encoding,
|
||||
file_encoding: Encoding,
|
||||
config: &ExtraConfig,
|
||||
) -> Result<()> {
|
||||
let f = std::fs::File::create(output_filename)?;
|
||||
let f = std::io::BufWriter::new(f);
|
||||
self.create_file(filename, Box::new(f), encoding, file_encoding)
|
||||
self.create_file(filename, Box::new(f), encoding, file_encoding, config)
|
||||
}
|
||||
|
||||
#[cfg(feature = "image")]
|
||||
|
||||
@@ -401,16 +401,18 @@ pub struct DscEncoder<'a, T: Write + Seek> {
|
||||
magic: u32,
|
||||
key: u32,
|
||||
dec_count: u32,
|
||||
min_len: usize,
|
||||
}
|
||||
|
||||
impl<'a, T: Write + Seek> DscEncoder<'a, T> {
|
||||
pub fn new(writer: &'a mut T) -> Self {
|
||||
pub fn new(writer: &'a mut T, min_len: usize) -> Self {
|
||||
let stream = MsbBitWriter::new(writer);
|
||||
DscEncoder {
|
||||
stream,
|
||||
magic: 0x5344 << 16, // "DS"
|
||||
key: rand::rng().random(),
|
||||
dec_count: 0,
|
||||
min_len,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -419,7 +421,6 @@ impl<'a, T: Write + Seek> DscEncoder<'a, T> {
|
||||
let mut ops = vec![];
|
||||
let mut pos = 0;
|
||||
|
||||
const MIN_LEN: usize = 2;
|
||||
const MAX_LEN: usize = 257;
|
||||
const WINDOW_SIZE: usize = 4097;
|
||||
|
||||
@@ -431,7 +432,7 @@ impl<'a, T: Write + Seek> DscEncoder<'a, T> {
|
||||
let mut best_len = 0;
|
||||
let mut best_offset = 0;
|
||||
|
||||
if max_len >= MIN_LEN {
|
||||
if max_len >= self.min_len {
|
||||
let limit = pos.saturating_sub(WINDOW_SIZE);
|
||||
let key = (data[pos] as u16) << 8 | data[pos + 1] as u16;
|
||||
let mut match_pos_i32 = head[key as usize];
|
||||
@@ -463,7 +464,7 @@ impl<'a, T: Write + Seek> DscEncoder<'a, T> {
|
||||
}
|
||||
}
|
||||
|
||||
if best_len >= MIN_LEN && best_offset >= 2 {
|
||||
if best_len >= self.min_len && best_offset >= 2 {
|
||||
ops.push(LzssOp::Match {
|
||||
len: best_len as u16,
|
||||
offset: best_offset as u16,
|
||||
@@ -574,10 +575,10 @@ impl ScriptBuilder for DscBuilder {
|
||||
_filename: &str,
|
||||
_encoding: Encoding,
|
||||
_archive_encoding: Encoding,
|
||||
_config: &ExtraConfig,
|
||||
config: &ExtraConfig,
|
||||
_archive: Option<&Box<dyn Script>>,
|
||||
) -> Result<Box<dyn Script>> {
|
||||
Ok(Box::new(Dsc::new(buf)?))
|
||||
Ok(Box::new(Dsc::new(buf, config)?))
|
||||
}
|
||||
|
||||
fn extensions(&self) -> &'static [&'static str] {
|
||||
@@ -605,8 +606,9 @@ impl ScriptBuilder for DscBuilder {
|
||||
mut writer: Box<dyn WriteSeek + 'a>,
|
||||
_encoding: Encoding,
|
||||
_file_encoding: Encoding,
|
||||
config: &ExtraConfig,
|
||||
) -> Result<()> {
|
||||
let encoder = DscEncoder::new(&mut writer);
|
||||
let encoder = DscEncoder::new(&mut writer, config.bgi_compress_min_len);
|
||||
let data = crate::utils::files::read_file(filename)?;
|
||||
encoder.pack(&data)?;
|
||||
Ok(())
|
||||
@@ -616,16 +618,20 @@ impl ScriptBuilder for DscBuilder {
|
||||
#[derive(Debug)]
|
||||
pub struct Dsc {
|
||||
data: Vec<u8>,
|
||||
min_len: usize,
|
||||
}
|
||||
|
||||
impl Dsc {
|
||||
pub fn new(buf: Vec<u8>) -> Result<Self> {
|
||||
pub fn new(buf: Vec<u8>, config: &ExtraConfig) -> Result<Self> {
|
||||
if buf.len() < 16 || !buf.starts_with(b"DSC FORMAT 1.00\0") {
|
||||
return Err(anyhow::anyhow!("Invalid DSC format"));
|
||||
}
|
||||
let decoder = DscDecoder::new(&buf)?;
|
||||
let data = decoder.unpack()?;
|
||||
Ok(Dsc { data })
|
||||
Ok(Dsc {
|
||||
data,
|
||||
min_len: config.bgi_compress_min_len,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -659,9 +665,13 @@ impl Script for Dsc {
|
||||
_encoding: Encoding,
|
||||
_output_encoding: Encoding,
|
||||
) -> Result<()> {
|
||||
let encoder = DscEncoder::new(&mut file);
|
||||
let encoder = DscEncoder::new(&mut file, self.min_len);
|
||||
let data = crate::utils::files::read_file(custom_filename)?;
|
||||
encoder.pack(&data)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_min_length(len: &str) -> Result<usize, String> {
|
||||
clap_num::number_range(len, 2, 256)
|
||||
}
|
||||
|
||||
@@ -512,6 +512,7 @@ pub struct BgiArchiveWriter<T: Write + Seek> {
|
||||
headers: HashMap<String, BgiFileHeader>,
|
||||
compress_file: bool,
|
||||
encoding: Encoding,
|
||||
min_len: usize,
|
||||
}
|
||||
|
||||
impl<T: Write + Seek> BgiArchiveWriter<T> {
|
||||
@@ -540,6 +541,7 @@ impl<T: Write + Seek> BgiArchiveWriter<T> {
|
||||
headers,
|
||||
compress_file: config.bgi_compress_file,
|
||||
encoding,
|
||||
min_len: config.bgi_compress_min_len,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -561,7 +563,7 @@ impl<T: Write + Seek> Archive for BgiArchiveWriter<T> {
|
||||
pos: 0,
|
||||
};
|
||||
Ok(if self.compress_file {
|
||||
Box::new(BgiArchiveFileWithDsc::new(file))
|
||||
Box::new(BgiArchiveFileWithDsc::new(file, self.min_len))
|
||||
} else {
|
||||
Box::new(file)
|
||||
})
|
||||
@@ -640,13 +642,15 @@ impl<'a, T: Write + Seek> Seek for BgiArchiveFile<'a, T> {
|
||||
pub struct BgiArchiveFileWithDsc<'a, T: Write + Seek> {
|
||||
writer: BgiArchiveFile<'a, T>,
|
||||
buf: MemWriter,
|
||||
min_len: usize,
|
||||
}
|
||||
|
||||
impl<'a, T: Write + Seek> BgiArchiveFileWithDsc<'a, T> {
|
||||
pub fn new(writer: BgiArchiveFile<'a, T>) -> Self {
|
||||
pub fn new(writer: BgiArchiveFile<'a, T>, min_len: usize) -> Self {
|
||||
BgiArchiveFileWithDsc {
|
||||
writer,
|
||||
buf: MemWriter::new(),
|
||||
min_len,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -678,7 +682,7 @@ impl<'a, T: Write + Seek> Seek for BgiArchiveFileWithDsc<'a, T> {
|
||||
impl<'a, T: Write + Seek> Drop for BgiArchiveFileWithDsc<'a, T> {
|
||||
fn drop(&mut self) {
|
||||
let buf = self.buf.as_slice();
|
||||
let encoder = DscEncoder::new(&mut self.writer);
|
||||
let encoder = DscEncoder::new(&mut self.writer, self.min_len);
|
||||
if let Err(e) = encoder.pack(&buf) {
|
||||
eprintln!("Failed to write DSC data: {}", e);
|
||||
crate::COUNTER.inc_error();
|
||||
|
||||
@@ -514,6 +514,7 @@ pub struct BgiArchiveWriter<T: Write + Seek> {
|
||||
headers: HashMap<String, BgiFileHeader>,
|
||||
compress_file: bool,
|
||||
encoding: Encoding,
|
||||
min_len: usize,
|
||||
}
|
||||
|
||||
impl<T: Write + Seek> BgiArchiveWriter<T> {
|
||||
@@ -543,6 +544,7 @@ impl<T: Write + Seek> BgiArchiveWriter<T> {
|
||||
headers,
|
||||
compress_file: config.bgi_compress_file,
|
||||
encoding,
|
||||
min_len: config.bgi_compress_min_len,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -564,7 +566,7 @@ impl<T: Write + Seek> Archive for BgiArchiveWriter<T> {
|
||||
pos: 0,
|
||||
};
|
||||
Ok(if self.compress_file {
|
||||
Box::new(BgiArchiveFileWithDsc::new(file))
|
||||
Box::new(BgiArchiveFileWithDsc::new(file, self.min_len))
|
||||
} else {
|
||||
Box::new(file)
|
||||
})
|
||||
@@ -643,13 +645,15 @@ impl<'a, T: Write + Seek> Seek for BgiArchiveFile<'a, T> {
|
||||
pub struct BgiArchiveFileWithDsc<'a, T: Write + Seek> {
|
||||
writer: BgiArchiveFile<'a, T>,
|
||||
buf: MemWriter,
|
||||
min_len: usize,
|
||||
}
|
||||
|
||||
impl<'a, T: Write + Seek> BgiArchiveFileWithDsc<'a, T> {
|
||||
pub fn new(writer: BgiArchiveFile<'a, T>) -> Self {
|
||||
pub fn new(writer: BgiArchiveFile<'a, T>, min_len: usize) -> Self {
|
||||
BgiArchiveFileWithDsc {
|
||||
writer,
|
||||
buf: MemWriter::new(),
|
||||
min_len,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -681,7 +685,7 @@ impl<'a, T: Write + Seek> Seek for BgiArchiveFileWithDsc<'a, T> {
|
||||
impl<'a, T: Write + Seek> Drop for BgiArchiveFileWithDsc<'a, T> {
|
||||
fn drop(&mut self) {
|
||||
let buf = self.buf.as_slice();
|
||||
let encoder = DscEncoder::new(&mut self.writer);
|
||||
let encoder = DscEncoder::new(&mut self.writer, self.min_len);
|
||||
if let Err(e) = encoder.pack(&buf) {
|
||||
eprintln!("Failed to write DSC data: {}", e);
|
||||
crate::COUNTER.inc_error();
|
||||
|
||||
@@ -50,6 +50,7 @@ impl ScriptBuilder for BGIBsiScriptBuilder {
|
||||
writer: Box<dyn WriteSeek + 'a>,
|
||||
encoding: Encoding,
|
||||
file_encoding: Encoding,
|
||||
_config: &ExtraConfig,
|
||||
) -> Result<()> {
|
||||
create_file(filename, writer, encoding, file_encoding)
|
||||
}
|
||||
|
||||
@@ -57,6 +57,7 @@ impl ScriptBuilder for CstlScriptBuilder {
|
||||
writer: Box<dyn WriteSeek + 'a>,
|
||||
encoding: Encoding,
|
||||
file_encoding: Encoding,
|
||||
_config: &ExtraConfig,
|
||||
) -> Result<()> {
|
||||
create_file(filename, writer, encoding, file_encoding)
|
||||
}
|
||||
|
||||
@@ -61,6 +61,7 @@ impl ScriptBuilder for EscudeBinListBuilder {
|
||||
writer: Box<dyn WriteSeek + 'a>,
|
||||
encoding: Encoding,
|
||||
file_encoding: Encoding,
|
||||
_config: &ExtraConfig,
|
||||
) -> Result<()> {
|
||||
create_file(filename, writer, encoding, file_encoding)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user