diff --git a/Cargo.lock b/Cargo.lock index 09107d9..afe4485 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -235,7 +235,7 @@ dependencies = [ [[package]] name = "rustitch" -version = "0.2.1" +version = "0.2.2" dependencies = [ "png", "thiserror", @@ -250,7 +250,7 @@ checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" [[package]] name = "stitch-peek" -version = "0.1.3" +version = "0.1.4" dependencies = [ "anyhow", "clap", diff --git a/rustitch/src/jef/mod.rs b/rustitch/src/jef/mod.rs index 22ce9d4..8e680eb 100644 --- a/rustitch/src/jef/mod.rs +++ b/rustitch/src/jef/mod.rs @@ -1,7 +1,7 @@ mod palette; use crate::error::Error; -use crate::types::{ResolvedDesign, StitchCommand}; +use crate::types::{Color, RawDesign, ResolvedDesign, StitchCommand}; use palette::JEF_PALETTE; /// Parse a JEF (Janome) file from raw bytes into stitch commands and color info. @@ -15,7 +15,7 @@ use palette::JEF_PALETTE; /// /// Stitch data: 2 bytes per stitch (signed i8 dx, dy). /// Control codes: 0x80 0x01 = color change, 0x80 0x02 = jump, 0x80 0x10 = end. -type ParseResult = Result<(Vec, Vec<(u8, u8, u8)>), Error>; +type ParseResult = Result; pub fn parse(data: &[u8]) -> ParseResult { if data.len() < 116 { @@ -38,7 +38,7 @@ pub fn parse(data: &[u8]) -> ParseResult { // Read color table starting at offset 116 let color_table_start = 116; - let mut colors = Vec::with_capacity(color_count); + let mut colors: Vec = Vec::with_capacity(color_count); for i in 0..color_count { let entry_offset = color_table_start + i * 4; if entry_offset + 4 > data.len() { diff --git a/rustitch/src/jef/palette.rs b/rustitch/src/jef/palette.rs index 0b91fbc..5af1439 100644 --- a/rustitch/src/jef/palette.rs +++ b/rustitch/src/jef/palette.rs @@ -1,6 +1,8 @@ +use crate::types::Color; + /// Janome thread color palette (78 entries). /// Index 0 is a fallback; indices 1-77 correspond to standard Janome thread colors. -pub const JEF_PALETTE: [(u8, u8, u8); 78] = [ +pub const JEF_PALETTE: [Color; 78] = [ (0, 0, 0), // 0: Unknown / Black (0, 0, 0), // 1: Black (255, 255, 255), // 2: White diff --git a/rustitch/src/palette.rs b/rustitch/src/palette.rs index d11b2df..4fded68 100644 --- a/rustitch/src/palette.rs +++ b/rustitch/src/palette.rs @@ -1,6 +1,8 @@ +use crate::types::Color; + /// Brother PEC thread color palette (65 entries). /// Index 0 is a fallback; indices 1-64 correspond to standard Brother thread colors. -pub const PEC_PALETTE: [(u8, u8, u8); 65] = [ +pub const PEC_PALETTE: [Color; 65] = [ (0, 0, 0), // 0: Unknown (14, 31, 124), // 1: Prussian Blue (10, 85, 163), // 2: Blue @@ -70,7 +72,7 @@ pub const PEC_PALETTE: [(u8, u8, u8); 65] = [ /// Default high-contrast palette for formats without embedded color info (DST, EXP). /// Colors cycle on each color change. -pub const DEFAULT_PALETTE: [(u8, u8, u8); 12] = [ +pub const DEFAULT_PALETTE: [Color; 12] = [ (0, 0, 0), // Black (237, 23, 31), // Red (10, 85, 163), // Blue @@ -86,12 +88,12 @@ pub const DEFAULT_PALETTE: [(u8, u8, u8); 12] = [ ]; /// Look up a PEC palette color by index, clamping to valid range. -pub fn pec_color(idx: u8) -> (u8, u8, u8) { +pub fn pec_color(idx: u8) -> Color { PEC_PALETTE[(idx as usize).min(PEC_PALETTE.len() - 1)] } /// Build a color list for `n` thread slots by cycling through `DEFAULT_PALETTE`. -pub fn default_colors(n: usize) -> Vec<(u8, u8, u8)> { +pub fn default_colors(n: usize) -> Vec { (0..n) .map(|i| DEFAULT_PALETTE[i % DEFAULT_PALETTE.len()]) .collect() diff --git a/rustitch/src/pec.rs b/rustitch/src/pec.rs index 7b08911..73c4eb5 100644 --- a/rustitch/src/pec.rs +++ b/rustitch/src/pec.rs @@ -1,9 +1,9 @@ use crate::error::Error; use crate::pes::pec::{decode_stitches, parse_pec_header}; -use crate::types::{ResolvedDesign, StitchCommand}; +use crate::types::{Color, RawDesign, ResolvedDesign}; /// Parse a standalone PEC file (`#PEC0001` prefix + PEC data). -pub fn parse(data: &[u8]) -> Result<(Vec, Vec<(u8, u8, u8)>), Error> { +pub fn parse(data: &[u8]) -> Result { if data.len() < 8 || &data[0..8] != b"#PEC0001" { return Err(Error::InvalidHeader("missing #PEC0001 magic".into())); } @@ -13,7 +13,7 @@ pub fn parse(data: &[u8]) -> Result<(Vec, Vec<(u8, u8, u8)>), Err let commands = decode_stitches(&pec_data[stitch_offset..])?; // Map PEC palette indices to RGB colors - let colors: Vec<(u8, u8, u8)> = header + let colors: Vec = header .color_indices .iter() .map(|&idx| crate::palette::pec_color(idx)) diff --git a/rustitch/src/pes/mod.rs b/rustitch/src/pes/mod.rs index c9fa33c..6dff70f 100644 --- a/rustitch/src/pes/mod.rs +++ b/rustitch/src/pes/mod.rs @@ -7,7 +7,7 @@ pub use pec::PecHeader; // Re-export shared types for backward compatibility pub use crate::error::Error; pub use crate::palette::PEC_PALETTE; -pub use crate::types::{BoundingBox, ResolvedDesign, StitchCommand, StitchSegment}; +pub use crate::types::{BoundingBox, Color, ResolvedDesign, StitchCommand, StitchSegment}; pub struct PesDesign { pub header: PesHeader, @@ -37,7 +37,7 @@ pub fn parse(data: &[u8]) -> Result { /// Convert parsed PES design into renderable segments with absolute coordinates. pub fn resolve(design: &PesDesign) -> Result { - let colors: Vec<(u8, u8, u8)> = design + let colors: Vec = design .pec_header .color_indices .iter() diff --git a/rustitch/src/resolve.rs b/rustitch/src/resolve.rs index bd4371f..34dc3b1 100644 --- a/rustitch/src/resolve.rs +++ b/rustitch/src/resolve.rs @@ -1,11 +1,8 @@ use crate::error::Error; -use crate::types::{BoundingBox, ResolvedDesign, StitchCommand, StitchSegment}; +use crate::types::{BoundingBox, Color, ResolvedDesign, StitchCommand, StitchSegment}; /// Convert parsed stitch commands into renderable segments with absolute coordinates. -pub fn resolve( - commands: &[StitchCommand], - colors: Vec<(u8, u8, u8)>, -) -> Result { +pub fn resolve(commands: &[StitchCommand], colors: Vec) -> Result { let mut segments = Vec::new(); let mut x: f32 = 0.0; let mut y: f32 = 0.0; diff --git a/rustitch/src/sew.rs b/rustitch/src/sew.rs index cb5f019..2b8423b 100644 --- a/rustitch/src/sew.rs +++ b/rustitch/src/sew.rs @@ -1,10 +1,10 @@ use crate::error::Error; -use crate::types::{ResolvedDesign, StitchCommand}; +use crate::types::{Color, RawDesign, ResolvedDesign, StitchCommand}; const STITCH_DATA_OFFSET: usize = 0x1D78; /// Janome SEW thread color palette (first 80 entries). -const SEW_PALETTE: [(u8, u8, u8); 80] = [ +const SEW_PALETTE: [Color; 80] = [ (0, 0, 0), // 0: Unknown (0, 0, 0), // 1: Black (255, 255, 255), // 2: White @@ -100,7 +100,7 @@ const SEW_PALETTE: [(u8, u8, u8); 80] = [ /// - 0x10: normal stitch (read 2 signed bytes) /// - other: end /// - Y is negated -pub fn parse(data: &[u8]) -> Result<(Vec, Vec<(u8, u8, u8)>), Error> { +pub fn parse(data: &[u8]) -> Result { if data.len() < STITCH_DATA_OFFSET + 4 { return Err(Error::TooShort { expected: STITCH_DATA_OFFSET + 4, @@ -114,7 +114,7 @@ pub fn parse(data: &[u8]) -> Result<(Vec, Vec<(u8, u8, u8)>), Err } // Read thread palette indices - let colors: Vec<(u8, u8, u8)> = (0..color_count) + let colors: Vec = (0..color_count) .map(|i| { let off = 2 + i * 2; if off + 1 < data.len() { diff --git a/rustitch/src/types.rs b/rustitch/src/types.rs index bb8face..67dd2a9 100644 --- a/rustitch/src/types.rs +++ b/rustitch/src/types.rs @@ -7,6 +7,9 @@ pub enum StitchCommand { End, } +pub type Color = (u8, u8, u8); +pub type RawDesign = (Vec, Vec); + pub struct StitchSegment { pub x0: f32, pub y0: f32, @@ -24,6 +27,6 @@ pub struct BoundingBox { pub struct ResolvedDesign { pub segments: Vec, - pub colors: Vec<(u8, u8, u8)>, + pub colors: Vec, pub bounds: BoundingBox, } diff --git a/rustitch/src/xxx.rs b/rustitch/src/xxx.rs index ef20987..1f82de7 100644 --- a/rustitch/src/xxx.rs +++ b/rustitch/src/xxx.rs @@ -1,5 +1,5 @@ use crate::error::Error; -use crate::types::{ResolvedDesign, StitchCommand}; +use crate::types::{Color, RawDesign, ResolvedDesign, StitchCommand}; const HEADER_SIZE: usize = 256; @@ -15,7 +15,7 @@ const HEADER_SIZE: usize = 256; /// - 0x08 or 0x0A..0x17: color change /// - 0x7F: end of data /// - Color table after stitch data: skip 2 bytes, then color_count × i32 BE (0x00RRGGBB) -pub fn parse(data: &[u8]) -> Result<(Vec, Vec<(u8, u8, u8)>), Error> { +pub fn parse(data: &[u8]) -> Result { if data.len() < HEADER_SIZE + 2 { return Err(Error::TooShort { expected: HEADER_SIZE + 2, @@ -99,7 +99,7 @@ pub fn parse(data: &[u8]) -> Result<(Vec, Vec<(u8, u8, u8)>), Err commands.push(StitchCommand::End); // Read color table: color_count × i32 BE (0x00RRGGBB) - let colors = if color_table_start + color_count * 4 <= data.len() { + let colors: Vec = if color_table_start + color_count * 4 <= data.len() { (0..color_count) .map(|c| { let base = color_table_start + c * 4;