From 46f6e6104e0be6e2ff3ae5b2d7c6df64ae8e42f7 Mon Sep 17 00:00:00 2001 From: lifegpc Date: Sun, 29 Jun 2025 17:20:09 +0800 Subject: [PATCH] add new settings --- src/args.rs | 4 +++ src/main.rs | 2 ++ src/scripts/cat_system/image/hg3.rs | 56 +++++++++++++++++++++++++++-- src/types.rs | 2 ++ src/utils/img.rs | 2 +- 5 files changed, 62 insertions(+), 4 deletions(-) diff --git a/src/args.rs b/src/args.rs index f9223a5..1fb2672 100644 --- a/src/args.rs +++ b/src/args.rs @@ -106,6 +106,10 @@ pub struct Arg { #[arg(long, global = true)] /// CatSystem2 engine int archive password pub cat_system_int_encrypt_password: Option, + #[cfg(feature = "cat-system-img")] + #[arg(long, global = true, action = ArgAction::SetTrue)] + /// Draw CatSystem2 image on canvas (if canvas width and height are specified in file) + pub cat_system_image_canvas: bool, #[command(subcommand)] /// Command pub command: Command, diff --git a/src/main.rs b/src/main.rs index 172fff5..b01c622 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1260,6 +1260,8 @@ fn main() { bgi_img_scramble: arg.bgi_img_scramble.clone(), #[cfg(feature = "cat-system-arc")] cat_system_int_encrypt_password: arg.cat_system_int_encrypt_password.clone(), + #[cfg(feature = "cat-system-img")] + cat_system_image_canvas: arg.cat_system_image_canvas, }; match &arg.command { args::Command::Export { input, output } => { diff --git a/src/scripts/cat_system/image/hg3.rs b/src/scripts/cat_system/image/hg3.rs index fae8e23..37d1f85 100644 --- a/src/scripts/cat_system/image/hg3.rs +++ b/src/scripts/cat_system/image/hg3.rs @@ -67,10 +67,11 @@ struct Hg3Entry { pub struct Hg3Image { data: MemReader, entries: Vec<(Hg3Entry, usize, usize)>, + draw_canvas: bool, } impl Hg3Image { - pub fn new(buf: Vec, _config: &ExtraConfig) -> Result { + pub fn new(buf: Vec, config: &ExtraConfig) -> Result { let mut reader = MemReader::new(buf); let mut magic = [0u8; 4]; reader.read_exact(&mut magic)?; @@ -102,6 +103,7 @@ impl Hg3Image { Ok(Hg3Image { data: reader, entries, + draw_canvas: config.cat_system_image_canvas, }) } } @@ -133,7 +135,19 @@ impl Script for Hg3Image { m_info: entry.clone(), m_pixel_size: entry.bpp / 8, }; - Ok(reader.unpack()?) + let mut img = reader.unpack()?; + if self.draw_canvas { + if entry.canvas_width > 0 && entry.canvas_height > 0 { + img = draw_on_canvas( + img, + entry.canvas_width, + entry.canvas_height, + entry.offset_x, + entry.offset_y, + )?; + } + } + Ok(img) } } @@ -266,7 +280,7 @@ impl<'a> Hg3Reader<'a> { self.m_input.pos = self.m_info.header_size as usize; let mut image_type = [0; 8]; self.m_input.read_exact(&mut image_type)?; - if &image_type == b"img0000\0" { + if &image_type == b"img0000" { return self.unpack_img0000(); } else { return Err(anyhow::anyhow!("Unsupported image type: {:?}", image_type)); @@ -307,3 +321,39 @@ impl<'a> Hg3Reader<'a> { Ok(img) } } + +fn draw_on_canvas( + img: ImageData, + canvas_width: u32, + canvas_height: u32, + offset_x: u32, + offset_y: u32, +) -> Result { + let bytes_per_pixel = img.color_type.bpp(img.depth) as u32 / 8; + let mut canvas_data = vec![0u8; (canvas_width * canvas_height * bytes_per_pixel) as usize]; + let canvas_stride = canvas_width * bytes_per_pixel; + let img_stride = img.width * bytes_per_pixel; + + for y in 0..img.height { + let canvas_y = y + offset_y; + if canvas_y >= canvas_height { + continue; + } + let canvas_start = (canvas_y * canvas_stride + offset_x * bytes_per_pixel) as usize; + let img_start = (y * img_stride) as usize; + let copy_len = img_stride as usize; + if canvas_start + copy_len > canvas_data.len() { + continue; + } + canvas_data[canvas_start..canvas_start + copy_len] + .copy_from_slice(&img.data[img_start..img_start + copy_len]); + } + + Ok(ImageData { + width: canvas_width, + height: canvas_height, + color_type: img.color_type, + depth: img.depth, + data: canvas_data, + }) +} diff --git a/src/types.rs b/src/types.rs index 9a035fe..d518b00 100644 --- a/src/types.rs +++ b/src/types.rs @@ -205,6 +205,8 @@ pub struct ExtraConfig { pub bgi_img_scramble: Option, #[cfg(feature = "cat-system-arc")] pub cat_system_int_encrypt_password: Option, + #[cfg(feature = "cat-system-img")] + pub cat_system_image_canvas: bool, } #[derive(Clone, Copy, Debug, ValueEnum, PartialEq, Eq, PartialOrd, Ord)] diff --git a/src/utils/img.rs b/src/utils/img.rs index f2326d6..d7f4287 100644 --- a/src/utils/img.rs +++ b/src/utils/img.rs @@ -165,7 +165,7 @@ pub fn flip_image(data: &mut ImageData) -> Result<()> { if data.height <= 1 { return Ok(()); } - let row_size = data.data.len() / data.height as usize; + let row_size = data.color_type.bpp(data.depth) as usize * data.width as usize / 8; if row_size == 0 { return Ok(()); }