Skip to content

Commit

Permalink
Add first support to cpclib-cruncher
Browse files Browse the repository at this point in the history
  • Loading branch information
Krusty/Benediction committed Feb 13, 2025
1 parent a8d4c78 commit 8de705a
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 2 deletions.
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ members = [
"cpclib-xfer",
"cpclib-xfertool",
"cpclib-z80emu",
"cpclib",
"cpclib", "cpclib-crunch",
#"cpclib-bndbuild-ratatui",
# "cpclib-xferfs",
]
Expand All @@ -50,6 +50,7 @@ cpclib-bndbuild = { version = "0.7.0", path = "cpclib-bndbuild", default-feature
cpclib-bndbuild-tauri = { version = "0.1.0", path = "cpclib-bndbuild-tauri/src-tauri", default-features = false }
cpclib-common = { version = "0.9.0", path = "cpclib-common", default-features = false }
cpclib-cpr = { version = "0.7.0", path = "cpclib-cpr", default-features = false }
cpclib-crunch = { version = "0.1.0", path = "cpclib-crunch", default-features = false }
cpclib-crunchers = { version = "0.9.0", path = "cpclib-crunchers", default-features = false }
cpclib-disc = { version = "0.9.2", path = "cpclib-disc", default-features = false }
cpclib-image = { version = "0.9.0", path = "cpclib-image", default-features = false }
Expand All @@ -75,7 +76,7 @@ cc = "1.2.10"
cfg-if = "1.0.0"
chardetng = { version = "0.1.17", features = ["multithreading"] }
choice_nocase = "0.2.0"
clap = { version="4.5.26", features=["color"]}
clap = { version="4.5.26", features=["color", "derive"]}
codespan-reporting = "0.11.1"
#contracts = "0.6.3"
const_format = {version="0.2.34", features = ["fmt"]}
Expand Down Expand Up @@ -181,6 +182,7 @@ cpclib-bndbuild = { path = "./cpclib-bndbuild/" }
cpclib-bndbuild-tauri = { path = "./cpclib-bndbuild-tauri/src-tauri" }
cpclib-common = { path = "./cpclib-common/" }
cpclib-cpr = { path = "./cpclib-cpr/" }
cpclib-crunch = { path = "./cpclib-crunch/" }
cpclib-crunchers = { path = "./cpclib-crunchers/" }
cpclib-disc = { path = "./cpclib-disc/" }
cpclib-image = { path = "./cpclib-image/" }
Expand Down
2 changes: 2 additions & 0 deletions cpclib-asm/src/assembler/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ impl<'a> From<&'a Utf8Path> for Fname<'a, '_> {
}
}


impl<'a> From<&'a str> for Fname<'a, '_> {
fn from(value: &'a str) -> Self {
let p: &Utf8Path = value.into();
Expand Down Expand Up @@ -240,6 +241,7 @@ pub fn get_filename_to_read<S: AsRef<str>>(
AnyFileName::from(fname).path_for_base_filename(options, env)
}

/// TODO refactor and move that from asm stuff. Should be done only in the disc crate
/// Load a file and remove header if any
/// - if path is provided, this is the file name used
/// - if a string is provided, there is a search of appropriate filename
Expand Down
19 changes: 19 additions & 0 deletions cpclib-crunch/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[package]
name = "cpclib-crunch"
version = "0.1.0"
authors.workspace = true
edition.workspace = true
license.workspace = true
repository.workspace = true
homepage.workspace = true
description= "Cruncher for Amstrad CPC projects."


[dependencies]
cpclib-common = {workspace = true, features = ["cmdline"]}
cpclib-asm = {workspace = true} # just to load data :( shouldbe replaced by cpclib-disc
cpclib-crunchers = {workspace = true}
cpclib-disc = {workspace = true}

[lints]
workspace = true
93 changes: 93 additions & 0 deletions cpclib-crunch/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
use cpclib_common::camino::Utf8PathBuf;
use cpclib_common::clap;
use clap::{Parser, ValueEnum};
use cpclib_crunchers::{lzsa::LzsaVersion, CompressMethod};
use cpclib_disc::amsdos::{AmsdosFile, AmsdosFileName};

#[derive(Parser, Debug)]
#[command(version, about, long_about = None)]
struct CrunchArgs {

#[arg(short, long, help="Cruncher of interest")]
cruncher: Cruncher,

#[arg(short, long, help="Input file to compress. Can be a binary (my_file.o), an Amsdos file (FILE.BIN), a file in a disc (my_disc.dsk#FILE.BIN")]
input: Utf8PathBuf,

#[arg(short, long, help="Also crunch the header. This is useful for binary files where the first bytes still correspond to a valid amsdos header", default_value_t=false)]
keep_header: bool,

#[arg(short, long, help="Compressed output file. Can be a binary, an Amsdos file, a file in a disc")]
output: Utf8PathBuf
}

#[derive(Debug, ValueEnum, Clone)]
pub enum Cruncher {
Apultra,
Exomizer,
Lz4,
Lz48,
Lz49,
Lzsa1,
Lzsa2,
Shrinkler,
Zx0
}



fn main() {
let args = CrunchArgs::parse();

// TODO move loading code in the disc crate
let (data, header) = cpclib_asm::file::load_file(args.input.as_path(), &Default::default())
.map_err(|e| format!("Unable to load the input file {}.\n{}", args.input, e))
.unwrap();

// keep header if needed
let data = if args.keep_header {
if let Some(header) = header {
let mut header = header.as_bytes().to_vec();
let data: Vec<u8> = data.into();
header.extend_from_slice(&data);
header
} else {
eprintln!("There is no header in the input file");
data.into()
}

} else {
data.into()
};

// TODO eventually get additional options to properly parametrize them
let cruncher = match args.cruncher {
Cruncher::Apultra => CompressMethod::Apultra,
Cruncher::Exomizer => CompressMethod::Exomizer,
Cruncher::Lz4 => CompressMethod::Lz4,
Cruncher::Lz48 => CompressMethod::Lz48,
Cruncher::Lz49 => CompressMethod::Lz49,
Cruncher::Lzsa1 => CompressMethod::Lzsa(LzsaVersion::V1, None),
Cruncher::Lzsa2 => CompressMethod::Lzsa(LzsaVersion::V1, None),
Cruncher::Shrinkler => CompressMethod::Shrinkler(Default::default()),
Cruncher::Zx0 => CompressMethod::Zx0,
};

let crunched = cruncher.compress(&data)
.expect("Error when crunching file");

eprintln!("LIMITATION: current version systematically save a file with amsdos header.\nNext version will be more flexible");


let file = AmsdosFile::binary_file_from_buffer(
&AmsdosFileName::try_from(args.output.as_str()).expect("Invalid amsdos fname"),
0xc000,
0xc000,
&crunched
).expect("Error when creating the amsdos file");

std::fs::write(file.amsdos_filename().unwrap().unwrap().filename(), file.header_and_content())
.expect("Error when saving file");


}

0 comments on commit 8de705a

Please sign in to comment.