From ceb97a5394c94dfad01989d71d60c719d66f77ab Mon Sep 17 00:00:00 2001 From: lifegpc Date: Fri, 8 Aug 2025 23:29:53 +0800 Subject: [PATCH] Add new arg --- src/args.rs | 4 ++++ src/main.rs | 2 ++ src/scripts/circus/image/crx.rs | 27 +++++++++++++++++++++++++-- src/scripts/circus/image/crxd.rs | 12 +++++++----- src/types.rs | 2 ++ 5 files changed, 40 insertions(+), 7 deletions(-) diff --git a/src/args.rs b/src/args.rs index b5b17bf..73e52b3 100644 --- a/src/args.rs +++ b/src/args.rs @@ -263,6 +263,10 @@ pub struct Arg { #[arg(long, global = true, value_enum, default_value_t = crate::scripts::circus::image::crx::CircusCrxMode::Auto)] /// Circus CRX image row type mode pub circus_crx_mode: crate::scripts::circus::image::crx::CircusCrxMode, + #[cfg(feature = "circus-img")] + #[arg(long, global = true, action = ArgAction::SetTrue)] + /// Draw Circus CRX images on canvas (if canvas width and height are specified in file) + pub circus_crx_canvas: bool, #[arg(short = 'F', long, global = true, action = ArgAction::SetTrue)] /// Force all files in archive to be treated as script files. pub force_script: bool, diff --git a/src/main.rs b/src/main.rs index 4996ecc..4037b09 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1640,6 +1640,8 @@ fn main() { webp_lossless: arg.webp_lossless, #[cfg(feature = "webp")] webp_quality: arg.webp_quality, + #[cfg(feature = "circus-img")] + circus_crx_canvas: arg.circus_crx_canvas, }; match &arg.command { args::Command::Export { input, output } => { diff --git a/src/scripts/circus/image/crx.rs b/src/scripts/circus/image/crx.rs index 2960295..3bb870e 100644 --- a/src/scripts/circus/image/crx.rs +++ b/src/scripts/circus/image/crx.rs @@ -169,6 +169,7 @@ pub struct CrxImage { zstd: bool, zstd_compression_level: i32, row_type: CircusCrxMode, + canvas: bool, } impl std::fmt::Debug for CrxImage { @@ -230,9 +231,15 @@ impl CrxImage { zstd: config.circus_crx_zstd, zstd_compression_level: config.zstd_compression_level, row_type: config.circus_crx_mode.for_importing(), + canvas: config.circus_crx_canvas, }) } + pub fn with_canvas(mut self, canvas: bool) -> Self { + self.canvas = canvas; + self + } + pub fn draw_diff(&self, diff: &Self) -> Result { let base_header = &self.header; let diff_header = &diff.header; @@ -810,13 +817,29 @@ impl Script for CrxImage { data[i + 3] = a ^ alpha_flip; } } - Ok(ImageData { + let img = ImageData { width: self.header.width as u32, height: self.header.height as u32, depth: 8, color_type: self.color_type, data, - }) + }; + if self.canvas { + let (img_width, img_height) = if self.header.clips.is_empty() { + (self.header.width as u32, self.header.height as u32) + } else { + let clip = &self.header.clips[0]; + (clip.img_width as u32, clip.img_height as u32) + }; + return Ok(draw_on_canvas( + img, + img_width, + img_height, + self.header.inner_x as u32, + self.header.inner_y as u32, + )?); + } + Ok(img) } fn import_image<'a>( diff --git a/src/scripts/circus/image/crxd.rs b/src/scripts/circus/image/crxd.rs index d1df912..e68137b 100644 --- a/src/scripts/circus/image/crxd.rs +++ b/src/scripts/circus/image/crxd.rs @@ -90,7 +90,8 @@ impl CrxdImage { nf.set_file_name(name); let f = std::fs::File::open(nf)?; CrxImage::new(std::io::BufReader::new(f), config)? - }; + } + .with_canvas(false); let mut typ = [0; 4]; reader.read_exact(&mut typ)?; if typ == *b"CRXJ" { @@ -107,7 +108,7 @@ impl CrxdImage { return Ok(Self { base, diff }); } else if typ == *b"CRXG" { let reader = StreamRegion::with_start_pos(reader, 0x20)?; - let diff = CrxImage::new(reader, config)?; + let diff = CrxImage::new(reader, config)?.with_canvas(false); return Ok(Self { base, diff }); } Err(anyhow::anyhow!("Unsupported diff CRXD type: {:?}", typ)) @@ -129,16 +130,17 @@ impl CrxdImage { if typ == *b"CRXJ" { reader.seek_relative(4)?; let offset = reader.read_u32()?; - return Ok(CrxImage::new( + return Self::read_diff( archive .ok_or(anyhow::anyhow!("No archive provided"))? .open_file_by_offset(offset as u64)? .to_data()?, + archive, config, - )?); + ); } else if typ == *b"CRXG" { let reader = StreamRegion::with_start_pos(reader, 0x20)?; - return Ok(CrxImage::new(reader, config)?); + return Ok(CrxImage::new(reader, config)?.with_canvas(false)); } Err(anyhow::anyhow!("Unsupported diff CRXD type: {:?}", typ)) } diff --git a/src/types.rs b/src/types.rs index 0a0d716..162e995 100644 --- a/src/types.rs +++ b/src/types.rs @@ -263,6 +263,8 @@ pub struct ExtraConfig { pub webp_lossless: bool, #[cfg(feature = "webp")] pub webp_quality: u8, + #[cfg(feature = "circus-img")] + pub circus_crx_canvas: bool, } #[derive(Clone, Copy, Debug, ValueEnum, PartialEq, Eq, PartialOrd, Ord)]