From af189c3924402d806e365e33a530274c3fdead93 Mon Sep 17 00:00:00 2001 From: lifegpc Date: Tue, 29 Jul 2025 20:06:00 +0800 Subject: [PATCH] Add compression level support --- Cargo.lock | 25 +++++++++++++++++++++++++ Cargo.toml | 1 + src/args.rs | 19 +++++++++++++++++++ src/main.rs | 2 ++ src/scripts/cat_system/cst.rs | 10 +++++++--- src/types.rs | 2 ++ 6 files changed, 56 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b423fad..0eb4196 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -79,6 +79,12 @@ version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + [[package]] name = "bit-set" version = "0.8.0" @@ -167,6 +173,15 @@ dependencies = [ "clap_derive", ] +[[package]] +name = "clap-num" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "822c4000301ac390e65995c62207501e3ef800a1fc441df913a5e8e4dc374816" +dependencies = [ + "num-traits", +] + [[package]] name = "clap_builder" version = "4.5.38" @@ -648,6 +663,7 @@ dependencies = [ "anyhow", "blowfish", "clap", + "clap-num", "csv", "emote-psb", "encoding_rs", @@ -680,6 +696,15 @@ dependencies = [ "syn", ] +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + [[package]] name = "once_cell" version = "1.21.3" diff --git a/Cargo.toml b/Cargo.toml index d517d90..a041e24 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ edition = "2024" anyhow = "1" blowfish = { version = "0.9", optional = true } clap = { version = "4.5", features = ["derive"] } +clap-num = "1.2" csv = "1.3" emote-psb = { version = "0.5", optional = true } encoding_rs = "0.8" diff --git a/src/args.rs b/src/args.rs index 11baa71..b6c5b8f 100644 --- a/src/args.rs +++ b/src/args.rs @@ -1,6 +1,21 @@ use crate::types::*; use clap::{ArgAction, ArgGroup, Parser, Subcommand}; +#[cfg(feature = "flate2")] +fn parse_compression_level(level: &str) -> Result { + let lower = level.to_ascii_lowercase(); + if lower == "none" { + return Ok(0); + } else if lower == "best" { + return Ok(9); + } else if lower == "default" { + return Ok(6); + } else if lower == "fast" { + return Ok(1); + } + clap_num::number_range(level, 0, 9) +} + /// Tools for export and import scripts #[derive(Parser, Debug)] #[clap(group = ArgGroup::new("encodingg").multiple(false), group = ArgGroup::new("output_encodingg").multiple(false), group = ArgGroup::new("archive_encodingg").multiple(false), group = ArgGroup::new("artemis_indentg").multiple(false))] @@ -184,6 +199,10 @@ pub struct Arg { /// CatSystem2 CSTL script language, used to extract messages from CSTL script. /// If not specified, the first language will be used. pub cat_system_cstl_lang: Option, + #[cfg(feature = "flate2")] + #[arg(short = 'z', long, global = true, value_name = "LEVEL", value_parser = parse_compression_level)] + /// Zlib compression level. Default is 6. 0 means no compression, 9 means best compression. + pub zlib_compression_level: Option, #[command(subcommand)] /// Command pub command: Command, diff --git a/src/main.rs b/src/main.rs index 168033c..2dcb7d2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1449,6 +1449,8 @@ fn main() { artemis_ast_lang: arg.artemis_ast_lang.clone(), #[cfg(feature = "cat-system")] cat_system_cstl_lang: arg.cat_system_cstl_lang.clone(), + #[cfg(feature = "flate2")] + zlib_compression_level: arg.zlib_compression_level, }; match &arg.command { args::Command::Export { input, output } => { diff --git a/src/scripts/cat_system/cst.rs b/src/scripts/cat_system/cst.rs index f3f664f..c61f442 100644 --- a/src/scripts/cat_system/cst.rs +++ b/src/scripts/cat_system/cst.rs @@ -99,10 +99,11 @@ pub struct CstScript { data: MemReader, compressed: bool, strings: Vec, + compress_level: u32, } impl CstScript { - pub fn new(buf: Vec, encoding: Encoding, _config: &ExtraConfig) -> Result { + pub fn new(buf: Vec, encoding: Encoding, config: &ExtraConfig) -> Result { let mut reader = MemReader::new(buf); let mut magic = [0; 8]; reader.read_exact(&mut magic)?; @@ -168,6 +169,7 @@ impl CstScript { data: file, compressed: compressed_size != 0, strings, + compress_level: config.zlib_compression_level.unwrap_or(6), }) } } @@ -326,8 +328,10 @@ impl Script for CstScript { file.write_u32(0)?; // Compressed size file.write_u32(data.len() as u32)?; // Uncompressed size if self.compressed { - let mut encoder = - flate2::write::ZlibEncoder::new(&mut file, flate2::Compression::default()); + let mut encoder = flate2::write::ZlibEncoder::new( + &mut file, + flate2::Compression::new(self.compress_level), + ); encoder.write_all(&data)?; encoder.finish()?; let file_len = file.stream_position()?; diff --git a/src/types.rs b/src/types.rs index 8efe190..23f47e9 100644 --- a/src/types.rs +++ b/src/types.rs @@ -235,6 +235,8 @@ pub struct ExtraConfig { pub artemis_ast_lang: Option, #[cfg(feature = "cat-system")] pub cat_system_cstl_lang: Option, + #[cfg(feature = "flate2")] + pub zlib_compression_level: Option, } #[derive(Clone, Copy, Debug, ValueEnum, PartialEq, Eq, PartialOrd, Ord)]